José D.
José D.

Reputation: 4275

Circular dependencies C++

I'm trying to compile something like the following:

A.h

#include "B.h"
class A {
    B * b;
    void oneMethod();
    void otherMethod();
};

A.cpp

#include "A.h"
void A::oneMethod() { b->otherMethod() }
void A::otherMethod() {}

B.h

#include "A.h"
class B {
    A * a;
    void oneMethod();
    void otherMethod();
};

B.cpp

#include "B.h"       
void B::oneMethod() { a->otherMethod() }
void B::otherMethod() {}

Until now I haven't had problems using forward declarations, but I can use that now, because i can't use atributtes or methods of only-forward-declarated classes.

How can I solve this?

Upvotes: 2

Views: 153

Answers (4)

Robᵩ
Robᵩ

Reputation: 168646

You must defer using the members of a class until after that class is defined. In your case, that means moving some member function bodies to the bottom of the file:

class B;

class A {
    B * b;
    void oneMethod();
    void otherMethod() {}
};

class B {
    A * a;
    void oneMethod() { a->otherMethod() }
    void otherMethod() {}
};

inline void A::oneMethod() { b->otherMethod() }

Here is a typical solution in multiple files:

A.h

class B;
class A {
    B * b;
    void oneMethod();
    void otherMethod();
};

B.h

class A;
class B {
    A * a;
    void oneMethod();
    void otherMethod();
};

A.cpp

#include "A.h"
#include "B.h"

void A::oneMethod() { b->otherMethod() }
void A::otherMethod() {}

B.cpp

#include "A.h"
#include "B.h"

void B::oneMethod() { a->otherMethod() }
void B::otherMethod() {}

main.cpp

#include "A.h"
int main () { A a; a.oneMethod(); }

Upvotes: 1

Dan F
Dan F

Reputation: 17732

As long as I'm understanding your question right, all you need to do is this:

A.h

class B;// Forward declaration, the header only needs to know that B exists
class A {
    B * b;
    void oneMethod();
    void otherMethod();
};

A.cpp

#include "A.h"
#include "B.h"//Include in the .cpp since it is only compiled once, thus avoiding circular dependency
void A::oneMethod() { b->otherMethod() }
void A::otherMethod() {}

B.h

class A;// Forward declaration, the header only needs to know that A exists
class B {
    A * a;
    void oneMethod();
    void otherMethod();
};

B.cpp

#include "B.h" 
#include "A.h"//Include in the .cpp since it is only compiled once, thus avoiding circular dependency      
void B::oneMethod() { a->otherMethod() }
void B::otherMethod() {}

Upvotes: 2

Ryan Guthrie
Ryan Guthrie

Reputation: 688

Push the implementation of your functions into cpp files and then the cpp can include both headers.

Upvotes: 0

Ben Voigt
Ben Voigt

Reputation: 283694

In C++, unlike Java and C#, you can define a member function (providing its body) outside the class.

class A;
class B;

class A {
    B * b;
    void oneMethod();
    void otherMethod() {}
};

class B {
    A * a;
    void oneMethod();
    void otherMethod() {}
};

inline void A::oneMethod() { b->otherMethod(); }
inline void B::oneMethod() { a->otherMethod(); }

Upvotes: 6

Related Questions