Reputation: 101
i hope there's a simple answer to this. without getting too complicated i have two classes. an "Animal" and a "Cell" Cell contains an Animal as a member. Animal has methods that accept Cells in their parameters.
i'm just confused as to how i #include each class the others header? i've only ever had to go up a chain of classes and just included the last class header in the next and so on, but this circular situation has me a bit lost.
i hope that makes sense, any help greatly appreciated.
Upvotes: 0
Views: 1810
Reputation: 224
You can forward declare, but this doesn't completely solve the problem, it only lets you declare a pointer to that object, not use any functions/members inside that object. You can do this:
Animal.h
class Cell;
class Animal {
private:
Cell cell;
};
Animal.cpp
#include "Animal.h"
#include "Cell.h"
// Animal functions can use members/functions in Cell object here
Cell.h
class Animal;
class Cell
{
private:
Animal animal;
};
Cell.cpp
#include "Animal.h"
#include "Cell.h"
// Cell functions can use members/functions in Animal object here
This way both objects are able to completely use the features of the other (except in the headers, but that's fine)
Upvotes: 0
Reputation: 4824
You need to forward declare one of the classes so that the compiler knows about it. Kind of like, there's this class "Animal", i'll tell you what it is later.
Example:
class Animal;
class Cell
{
Animal *a;
};
class Animal
{
Cell *c;
};
As Gareth notes in the comments, you may not forward declare something that will be passed by value. This is because the compiler can only deal with types that it knows the size of. A pointer to anything is always the same size, so the compiler does require Animal to be fully defined in the above example.
This will not work:
class Animal;
class Cell
{
Animal a; // compiler needs to know how Animal is defined
} // and so will fail at this point
Upvotes: 3
Reputation: 137960
animal.h:
class Cell; // fwd declaration
// Cell is now an "incomplete type"
class Animal {
void Respirate( Cell & ); // reference: no need for complete type
};
cell.h:
#include "animal.h"
class Cell {
Animal organism; // conceptually, a reference or pointer would be better
};
OR
class Animal
class Cell {
Animal *organism; // Cell "knows about an" animal rather than "has an"
};
Upvotes: 1
Reputation:
It's not possible for two classes each to contain objects of the other's type - one or both of the classes will have to contain a pointer to the other's type.
Upvotes: 1
Reputation: 4112
You can use forward declarations to overcome the problem of circular references.
Example:
//animal.h
#include "cell.h"
class Animal {
public:
void foo (Cell cell);
}
// cell.h
class Animal; // forward declaration
class Cell {
private:
Animal * m_animal; // pointer to Animal object
}
Upvotes: 3
Reputation: 793329
If Cell
contains Animal
as a member then a full definition of Animal
is needed before Cell
is defined so you would need to #include
the header that defines Animal
from the header that defines Cell
.
#include "animal.h"
class Cell
{
// ...
Animal animal; // animal member
};
If Animal
has methods that take or return a Cell
(whether by reference or value) then you can just forward declare Cell
before the definition of Animal
like this.
// animal.h
class Cell;
class Animal
{
// declarations of Animal methods
};
Upvotes: 1
Reputation: 32067
Cyclic dependencies are handled with forward declarations (scroll to the bottom of the page).
Upvotes: 1