Solved

Mutual include statements between two .h files

Posted on 2004-10-11
16
389 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
 
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 150 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
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 86

Accepted Solution

by:
jkr earned 150 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

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Browsers only know CSS so your awesome SASS code needs to be translated into normal CSS. Here I'll try to explain what you should aim for in order to take full advantage of SASS.
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
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…
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

708 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now