Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Mutual include statements between two .h files

Posted on 2004-10-11
16
Medium Priority
?
398 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

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

Preface In the first article: A Better Website Login System (http://www.experts-exchange.com/A_2902.html) I introduced the EE Collaborative Login System and its intended purpose. In this article I will discuss some of the design consideratio…
Introduction Since I wrote the original article about Handling Date and Time in PHP and MySQL several years ago, it seemed like now was a good time to update it for object-oriented PHP.  This article does that, replacing as much as possible the pr…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

688 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