Friday, April 6, 2012

How to Resolve Circular Dependencies in C++

Having circular dependencies in C++ can cause the compiler to complain about having a type that wasn't declared. The solution is simple, that is to forward declare the class. But knowing such problem exists and how to resolve it can save a lot of time debugging. Let's consider this scenario below. A needs B and B needs A.
#ifndef A_H_
#define A_H_

class B; // forward declare B

class A {
public:
    A(B* b);
    void trigger();
    void execute();
    virtual ~A();

private:
    B* bptr;
};
#endif /* A_H_ */
In class A, we forward declare B. If we didn't forward declare B, we would get compilation error. The only catch for using forward declaration is the B must be a pointer type.
#include "A.h" // make sure to include A
#include "B.h"
#include <iostream>
using namespace std;

A::A(B* b) : bptr(b) {
}

void A::trigger() {
    bptr->executeA(this);
}

void A::execute() {
    cout << "Hello" << endl;
}

A::~A() {
}
Since we forward declare B in A.h header file, we need to include the actual B header file.
#ifndef B_H_
#define B_H_

#include "A.h"

class B {
public:
    B();
    void executeA(A* a);
    virtual ~B();
};

#endif /* B_H_ */
#include "B.h"

B::B() {
}

void B::executeA(A* a) {
    a->execute();
}

B::~B() {
}
#include "A.h"
#include "B.h"
using namespace std;

int main() {
    B b;
    A a(&b);
    a.trigger();
}

1 comment: