#include <iostream>
class BClass;
class AClass
{
private:
BClass* ptrBClass;
public:
void init(BClass* ptr);
void printB();
void print();
};
class BClass
{
private:
AClass& refAClass;
public:
BClass(AClass& refAClass);
void printA();
void print();
};
//define the functions after both class declarations
void AClass::init(BClass* ptr) { ptrBClass = ptr; }
void AClass::printB() { ptrBClass->print(); }
void AClass::print() { std::cout << 'a' << std::endl; }
BClass::BClass(AClass& refAClass) : refAClass(refAClass) { }
void BClass::printA() { refAClass.print(); }
void BClass::print() { std::cout << 'b' << std::endl; }
AClass aObject;
BClass bObject(aObject);
int main()
{
//the first object in a circlular depencency must initialize a pointer
//because a refernce could not be changed to refer to a different object
aObject.init(&bObject);
aObject.printB();
bObject.printA();
}
output is as expected:
1 2
b
a
The second example uses the same code as the first example, but the class declarations and implementations moved to separate files.
It gets these linker errors:
1 2 3 4 5 6 7
/tmp/ccLYmASa.o: In function `main':
circular_dependency.cpp:(.text+0xf): undefined reference to `AClass::init(BClass*)'
circular_dependency.cpp:(.text+0x19): undefined reference to `AClass::printB()'
circular_dependency.cpp:(.text+0x23): undefined reference to `BClass::printA()'
/tmp/ccLYmASa.o: In function `__static_initialization_and_destruction_0(int, int)':
circular_dependency.cpp:(.text+0x74): undefined reference to `BClass::BClass(AClass&)'
collect2: error: ld returned 1 exit status
How to fix the linker errors?
Thank you.
Example 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#include "AClass.h"
#include "BClass.h"
AClass aObject;
BClass bObject(aObject);
int main()
{
//the first object in a circlular depencency must initialize a pointer
//because a refernce could not be changed to refer to a different object
aObject.init(&bObject);
aObject.printB();
bObject.printA();
}
I was trying to make an example of a circular dependency that is simple and clear.
The solution will be applied to a real-world problem.
Each class contains a reference to the other class, which makes it a circular dependency.
In the real-world problem, the two classes are a State class and a Display class.
When the State class changes, it calls the Display class, passing relevant state information to the Display class, which then displays the state.
This is a one-way flow of information (not circular).
However, there is an exception that makes the State-Display relation circular.
One of the displays is animated and takes 2 seconds to complete.
The Display class does not store state information.
At the end of the 2 seconds, the Display class calls the State class to get the current state and then continues to display the current state.
The following code has the .cpp files #included in main, and it works.
This arrangement of #includes seems a bit strange to me. Is this how it is normally done?
Example 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include "AClass.h"
#include "BClass.h"
#include "AClass.cpp"
#include "BClass.cpp"
AClass aObject;
BClass bObject(aObject);
int main()
{
//the first object in a circlular depencency must initialize a pointer
//because a refernce could not be changed to refer to a different object
aObject.init(&bObject);
aObject.printB();
bObject.printA();
}