Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Mutual include statements between two .h files

Posted on 2004-10-11
16
Medium Priority
?
399 Views
Last Modified: 2013-11-18
I have two .H files, one class in each

A
and
B

B is defined and has a variable of type A *
which means that B has an include "A.h"

now, I have a situation that calls for A to know B as well
meaning that A will have a B * variabile
and will also need to include "B.h"

thats mutual include

when compiling B.h, the complier will not continue reading the include A.h after the point that include "B.h" appears in A.h
and therefore B has no idea who is A


what can I do to have both "know" each other and escape the compiler error.

btw, each .h file has a ifdef clause

#ifndef _INCLUDE_CFIELDS_H
#define _INCLUDE_CFIELDS_H
...
#endif

using MS Visual Studio.NET 2003,

thanks
0
Comment
Question by:moshem
  • 7
  • 4
  • 3
  • +1
16 Comments
 
LVL 13

Expert Comment

by:SteH
ID: 12277723
Is this include guard
#ifndef _INCLUDE_CFIELDS_H
#define _INCLUDE_CFIELDS_H
...
#endif
identical in each header? It should not be.
Try
#ifndef _INCLUDE_A_H
#define _INCLUDE_A_H
...
#endif
and
#ifndef _INCLUDE_B_H
#define _INCLUDE_B_H
...
#endif
0
 
LVL 1

Author Comment

by:moshem
ID: 12277752
it is not identical

one is the above

the second is:

#ifndef _INCLUDE_CFIELDS_H
#define _INCLUDE_CFIELDS_H
...
#endif
0
 
LVL 13

Expert Comment

by:SteH
ID: 12277768
Sorry but
#ifndef _INCLUDE_CFIELDS_H
#define _INCLUDE_CFIELDS_H
...
#endif
and
#ifndef _INCLUDE_CFIELDS_H
#define _INCLUDE_CFIELDS_H
...
#endif
look identical to me.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 1

Author Comment

by:moshem
ID: 12277790
sorry, my bad.

the second is:

#ifndef _INCLUDE_CRULES_H
#define _INCLUDE_CRULES_H
...
#endif
0
 
LVL 12

Assisted Solution

by:stefan73
stefan73 earned 600 total points
ID: 12277795
Hi moshem,
Use a class forward declaration:

class B;

class A{
    B* myB;
};

class B{
    A* myA;
}

This works fine, as long as you don't dereference B (you can't) -> You can only dereference B in methods which know already how B looks like.

Cheers!

Stefan
0
 
LVL 86

Expert Comment

by:jkr
ID: 12277798
You'd usually use a foward declaration for that, e.g. like

//a.h
#ifndef A_H
#define A_H
#include "b.h"
#ifndef B_DEFINED
class B;
#endif
class A {

//...

B* pb;
};
#define A_DEFINED
#endif

//b.h
#ifndef B_H
#define B_H
#include "a.h"
#ifndef A_DEFINED
class A;
#endif
class B {

//...

A* pa;
};
#define B_DEFINED
#endif
0
 
LVL 12

Expert Comment

by:stefan73
ID: 12277865
moshem,
It's a good habit to use a forward declaration of used class attributes in all class declarations, like:

A.h:

class B;
class A{
    B* myB;
    ...
};

B.h:
class A;
class B{
    A* myA;
}

(don't forget the #ifdef wrappers)

Include a class definition only if you need to inherit from another class.
Now you can simply do in all your .cpp files:

#include <A.h>
#include <B.h>

...without having to worry about the underlying include order. That pretty much decouples class dependencies and is as close as you can get in C++ in comparison to languages with a more advanced reference concept for class declarations (such as Java, Ruby, etc.)

0
 
LVL 1

Author Comment

by:moshem
ID: 12277896
well, I tried using forward declration the problem is I need to use the pointer to access members of the class so just defining the name wont cut it.

I need to have a way, to access the member funcitons of B from A using B *, and using forward declarations won't give me access to member functions AFAIK.

the current situations is that B includes A, has a pointer to A * and uses it's members.

now I need to have A include B, have a B * pointer and use at least one member function.

any ideas ?
0
 
LVL 86

Accepted Solution

by:
jkr earned 600 total points
ID: 12277955
>>the problem is I need to use the pointer to access members of the class

Move that code out of the header file and into the implementation file and you're rid of the problem. That's where it should go to anyway.
0
 
LVL 1

Author Comment

by:moshem
ID: 12277986
true, in this case I used only .h files and the code is in the method declaration, do I understand what you are saying , that spliting the code to an cpp file will solve the problem ? can you explain ?

btw, will I still need to use forward declaration ?

thanks.
0
 
LVL 86

Expert Comment

by:jkr
ID: 12278098
>>that spliting the code to an cpp file will solve the problem ? can you explain ?

Yes, if you only are using pointers. If you start accessing members via that pointers, trouble will start again

>>btw, will I still need to use forward declaration ?

Yes.
0
 
LVL 1

Author Comment

by:moshem
ID: 12278505
>>Yes, if you only are using pointers. If you start accessing members via that pointers, trouble will start again

what do you mean ?

I want to do:

 B * p;

p->Method (arg1,arg2);


I will check it out and report back later on
0
 
LVL 86

Expert Comment

by:jkr
ID: 12278555
>>>>Yes, if you only are using pointers. If you start accessing members via that pointers, trouble will start again
>>what do you mean ?

I mean that the trouble will start all over if you are actually using the pointers in the header file. That should go to the implementation file.
0
 
LVL 1

Author Comment

by:moshem
ID: 12282073
Ok, I tried it , I still dont know if this works since I have a problem with the forward declarations.

I used forward declrations like this:

struct associated_data_type;
struct field_entity_struct;
typedef type_field_entity_map_iterator;
struct field_struct;
class CFields;

all works except the typedef,when the compiler encounters the real typedef defenition in the original file it complains about redefinition with differnet base types.

the full defenition is:

typedef std::map <std::string, field_entity_struct>::iterator  type_field_entity_map_iterator;


how can I also forward these typedefs which are neccessary for the compilation ?

thanks
0
 
LVL 1

Author Comment

by:moshem
ID: 12282297
never mind, I just declared the typedef in it's full form in both .h files and it compiles ok.

if you have other better ideas let me know.

0
 
LVL 12

Expert Comment

by:stefan73
ID: 12285234
If the typedef is not related to your classes (normally, it should!),
define the typedef in a generic, prologue-style .h file:

generic.h:
<some includes>
typedef std::map <std::string, field_entity_struct>::iterator  type_field_entity_map_iterator;

...and then make sure that every class definition file includes this file first. Be aware that by this, you add order dependencies to your includes, which is not good.

So check if you can place it into your classes - an iterator is normally belonging to a class.

BTW: Separating class definition and implementation is A Good Thing.

Imagine a larger project with lots of interdependent classes - implementation changes are normally more frequent than definition changes, so you don't have to recompile everything again (by make or otherwise) for a tiny implementation change.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preface This article introduces an authentication and authorization system for a website.  It is understood by the author and the project contributors that there is no such thing as a "one size fits all" system.  That being said, there is a certa…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
Suggested Courses

916 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question