0

I know circular dependency can be resolved by forward declaration and pointer like this:

A.h

class B;
class A{
public:
    void update(B* b);
    void test(){}
};

A.cpp

#include "A.h"
#include "B.h"
void A::update(B* b){
    b->test();
}

B.h

class A;
class B{
public:
    void update(A* a);
    void test(){}
};

B.cpp

#include "B.h"
#include "A.h"
void B::update(A* a){
    a->test();
}

so that the code above can compile with containing each other,but the problem is, why can it be said as "resolving circular dependency"? I was not satisfying that "B" still exists in source code of A and "A" still exists in source code of B. At least I think it should change the design pattern so that no class can contain each other,e.g,using a parent class to hold A and B.:

Parent.h

class A;
class B;
class Parent{
    void update(A* a,B* b);
};

Parent.cpp

void Parent::update(A* a,B* b){
    a->test();
    b->test();
}

why using forward declaration and pointer can said to be "resolve circular dependency" even the source code still contains each other?

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
ggrr
  • 7,737
  • 5
  • 31
  • 53
  • 4
    It resolves the errors you get if trying to include the header files into each other. That's what is meant. The classes still depend on each other. – πάντα ῥεῖ Aug 10 '15 at 06:33

2 Answers2

4

When you have A.h with the line:

#include "B.h"

and B.h with the line:

#include "A.h"

there is a circular dependency between A.h and B.h. When two header files are circularly dependent, it creates problems at compile time. You can avoid them by using forward declarations.

It does not preclude A.cpp with lines:

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

and

B.cpp with lines:

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

Implementation of A can depend on the definitions of A as well as B.
Implementation of B can depend on the definitions of A as well as B.

In that case, the classes are circularly dependent but not in the same sense two header files can be circularly dependent.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

Forward declaring a pointer resolves the circular dependency, because the compiler doesn't need to know the content of the struct or class to be pointed. It needs to know the size of some pointer sizeof *p == sizeof void * to be inserted, and which will have the correct semantics after both classes or structs have been fully defined.

A counter example is:

struct A { struct B b; }; struct B { struct A a; };

Even when one or both of those structs was forward declared, the content would have to be known before the closing brace '}'. This "clearly" isn't the case.

Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57