Reputation: 13
I've read a lot of circular dependecies topics, but I couldn't find the one solving my problem. I have two classes containing pointers to each other:
class B;
class A
{
public:
A(B* _b, int _c): b(_b), c(_c) {}
B* b;
int c;
};
class B
{
public:
B(A* _a, int _d): a(_a), d(_d) {}
A* a;
int d;
};
The problem is that in the following code:
class C
{
public:
A* a_ptr;
B* b_ptr;
C()
{
a_ptr = new A(b_ptr, 3);
b_ptr = new B(a_ptr, 2);
qDebug() << a_ptr->c;
qDebug() << b_ptr->d;
qDebug() << a_ptr->b->d;
qDebug() << b_ptr->a->c;
}
}
last two lines are crashing application. I understand the problem and the reason of crashes. I could write setters for members and invoke them AFTER creating objects, so the pointers will be valid. However, I want the objects to be complete after invoking contructors, without invoking any other methods.
So... I was wondering if there is any way to inject (cyclic) pointers in constructors?
Upvotes: 1
Views: 215
Reputation: 9388
You can make one contructor complete the initialization of the other object:
B(A* a_ptr) : a(a_ptr)
{
if(a)
a->b = this;
}
And same for A()
. Thus, you can create them like the following:
a_ptr = new A(b_ptr, 3); // b_ptr was initialized to 0
b_ptr = new B(a_ptr, 2); // b_ptr->a = a_ptr
// b_ptr->a->b = b_ptr (ie, a_ptr->b = b_ptr)
Edit: As stated in the comment, this is not scalable if you have a lot of classes. However, in the general case you will have to initialize cyclic dependencies outside of constructors, and secondly you shouldn't have a a lot of classes that cyclicly depends on each other (if it is the case, maybe you can rearrange your code...).
Upvotes: 2