Solved

Mutual include statements between two .h files

Posted on 2004-10-11
16
394 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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
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
 
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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

There are two main kinds of selectors in CSS: One is base selector like h1, h2, body, table or any existing HTML tags.  For instance, the following rule sets all paragraphs (<p> elements) to red: (CODE) CSS also allows us to define our own custom …
Shoutout to Emily Plummer (http://www.experts-exchange.com/members/eplummer26.html) for giving me this article! She did most of it, I just finished it up and posted it for her :)    Introduction In a previous article (http://www.experts-exchang…
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

808 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