• Advertisement
Sign in to follow this  

Using 2 Classes that include each other

This topic is 4789 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Basically here's what I have:
//Class A
#include "ClassB"

class A{
A(B)
}

//Class B
#include "ClassA"
B()...
private:
A;
Is there any way to make this work?

Share this post


Link to post
Share on other sites
Advertisement
you need a class declaration.


//Class A

#include "ClassB"



class A{

A(B)

}



//Class B

class ClassA;

B()...

private:

A;


note the "class ClassA". this tells the compiler "there is a class called ClassA out there, and you will know about him at compile time".

Share this post


Link to post
Share on other sites
because when you do forward declaration you can only create the object dinamically.

I mean:

class a;

class b
{
a myA; // <---wont work
};


You need to make myA a pointer:

class a;

class b
{
a* myA; // <---WILL work
b() //constructor
{
a = new a();
}

};

Share this post


Link to post
Share on other sites
Quote:
Original post by Sfpiano
Then it tells me I'm using an undefined class.


Because a class declaration only allows you to create pointers, references to that class, or to declare functions that return or take it as parameter.

Code that actually creates variable of the class type require a full definition, as there is no other way for the compiler to know the actual size of the variable.

In your example, since A only uses B as a function parameter, it can make do with a declaration for B. However, B has a member of type A (not A* nor A&) and thus needs the full definition for A.

Share this post


Link to post
Share on other sites
Ok, when I do that it tells me my class has no constructors:
A::Init() {
a = new B();
}

Share this post


Link to post
Share on other sites
then add a constructor B::B(){} to your class.

and make it public! I wonder why it doesn't use the default one.

ah, don't forget to do #include "B.h" in A.cpp

Share this post


Link to post
Share on other sites
Ok, here's my code:

//Graph.h
#include "Geo.h"
class Graph {
public:
Graph();
Graph( Geo &obj );
...
}

//Geo.h
class Graph;

class Geo {
private:
Graph* graph;
...
}

//Geo.cpp
Geo::Geo() {
graph = new Graph();
}


And it tells me Graph has no constructors.

Share this post


Link to post
Share on other sites
Quote:
Original post by owl
because when you do forward declaration you can only create the object dinamically.

I mean:

class a;

class b
{
a myA; // <---wont work
};


EDIT: Fixed some stuff; see my later post.


// a.h

#ifndef _PROTECT_A_H
#define _PROTECT_A_H

#include "b.h"

class a
{
private:
b myB;

public:
a(); // declare functions here, but don't define it
~a();

void SomeFunction();

};

#endif // #ifndef _PROTECT_A_H







// a.cpp

#include "a.h" // include a's header

a::a()
{
// do something
}
a::~a()
{
// do something
}

void a::SomeFunction()
{
// do something
}








// b.h

#ifndef _PROTECT_B_H
#define _PROTECT_B_H

class a;

class b
{
private:

public:
b(); // declare functions here, but don't define it
~b();

void AnotherFunction(a& SomeA);

};

#endif // #ifndef _PROTECT_B_H







// b.cpp

#include "b.h" // first include b's header
#include "a.h" // now include a's header to override the empty defnition of a
// provided in b.h

// now define the functions. Because a.h and b.h are included in this file,
// we can make full use of both class b and class a
b::b()
{
// do something
}
b::~b()
{
// do something
}

void b::AnotherFunction(a& SomeA)
{
// do something
}






The rule when you want to have two classes that make use of each other is:
1. In the .h files, add blank class declarations of the other class(es).
2. In the .cpp files, first include the associated header file and then include the header files for each of the classes that have blank definitions at the top of the associated header file.
EDIT: 3. All member function defnitions (as opposed to declarations) that make any use of another class that is given a blank definition in the first class' .h file must be put in the .cpp of the first class, not the .h file.
This will work with basically any set of classes, with the exception that you have to do ugly things to make it work with template classes.

[Edited by - mumpo on January 7, 2005 6:05:31 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by mumpo
Quote:
Original post by owl
because when you do forward declaration you can only create the object dinamically.

I mean:

class a;

class b
{
a myA; // <---wont work
};


Wrong! You don't have to declare dynamically. What you must do is split the information into multiple files:

*** Source Snippet Removed ***

*** Source Snippet Removed ***


*** Source Snippet Removed ***

*** Source Snippet Removed ***

The rule when you want to have two classes that make use of each other is:
1. In the .h files, add blank class declarations of the other class(es).
2. In the .cpp files, first include the associated header file and then include the header files for each of the classes that have blank definitions at the top of the associated header file.
EDIT: 3. All member function defnitions (as opposed to declarations) that make any use of another class that is given a blank definition in the first class' .h file must be put in the .cpp of the first class, not the .h file.
This will work with basically any set of classes, with the exception that you have to do ugly things to make it work with template classes.


What is funny is that your code won't compile. I'm glad OP got it working anyway.

Share this post


Link to post
Share on other sites
I apologize. I didn't actually test my code before I posted it (a bad idea, I know). It only needed a small modification to work, but that modification changes it so that it does not disagree with owl's post. However, it IS true that it is not necessarily required that you use a pointer because if the two classes do not need to include members of eachother's types, but rather simply need to refer to one another, or one needs to have a member of the other's type, but not vice-versa, you can use the code like the fixed code that should now show up in my previous post.

Share this post


Link to post
Share on other sites
Quote:
Original post by mumpo
I apologize.


Thank you++

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement