views:

129

answers:

2

In C++ I have a reference to an object that wants to point back to its owner, but I can't set the pointer during the containing class' construction because its not done constructing. So I'm trying to do something like this:

class A {
   public:

     A() : b(this) {}
   private:
     B b;
};

class B {
   public:
     B(A* _a) : a(_a) {}
   private:
     A* a;
};

Is there a way to ensure B always gets initialized with an A* without A holding a pointer to B?

Thanks

+6  A: 

Try this:

class A;

class B {
public:
  B(A *_a) : a(_a) {};

private:
  A* a;
};

class A {
public:
  A() : b(this) {};

private:
  B b;

};

Since B is contained completely in A, it must be declared first. It needs a pointer to A, so you have to forward-declare A before you declare B.

This code compiles under more-or-less current versions of g++.

Michael Kohne
A: 

In C++ I have a reference to an object that wants to point back to its owner, but I can't set the pointer during the containing class' construction because its not done constructing.

You can store the pointer alright.

What you can't do is to try to get to the members/methods of A through the pointer in the constructor of B, since the parent instance might not be fully initialized at the point:

#include <iostream>

class Y;

class X
{
    Y* y;
public:
    X(Y* y);
};

class Y
{
    X x;
    int n;
public:
    Y(): x(this), n(42) {}
    int get_n() const { return n; }
};

X::X(Y* p): y(p)
{
    //Now this is illegal:
    //as it is, the n member has not been initialized yet for parent
    //and hence get_n will return garbage
    std::cout << p->get_n() << '\n';
}

int main()
{
    Y y;
}

If you were to switch around the members in Y, so n would get initialized first, the constructor of X would print 42, but that is too fragile to depend on.

UncleBens