By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,142 Members | 910 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,142 IT Pros & Developers. It's quick & easy.

Inside a constructor: can you assign the "this" pointer to a sub-object?

P: n/a
During construction of an object "parent", if you create a subobject
that stores a pointer to the parent (through the "this" pointer), will
that pointer be valid when the subobject is later called?

class Parent
{
Parent::Parent() { child = new Child( this) };
Child *child;
};

class Child
{
Child::Child( Parent *par) { myParent = par };
Parent *myParent;
}

Will myParent be the correct address when child is subsequently
accessed?

Any comments greatly appreciated.

Craig

Aug 12 '06 #1
Share this Question
Share on Google+
4 Replies


P: n/a
"craig" <cr**********@comcast.netschrieb im Newsbeitrag
news:11**********************@i42g2000cwa.googlegr oups.com...
During construction of an object "parent", if you create a subobject
that stores a pointer to the parent (through the "this" pointer), will
that pointer be valid when the subobject is later called?

class Parent
{
Parent::Parent() { child = new Child( this) };
Child *child;
};

class Child
{
Child::Child( Parent *par) { myParent = par };
Parent *myParent;
}

Will myParent be the correct address when child is subsequently
accessed?
As long as your new instance of Child does only save a copy of the pointer
for later use, it is safe. If -- in Child's constructor -- it uses the
pointer to access data or non-static functions of its parent, that may
result in unexpected or even undefined behaviour.

Imagin there are other classes derived from Parent and Parent has virtual
functions. If Child's constructor calls one of these virtual functions, the
implementation provided by Parent intself will be called, never that of a
derived class. If it is a pure virtual function, you'll have a problem.

The Parent object passed to child might not be properly initialized. Any
initialization Parent's constructor does after create a new Child, will not
be visible to the Child (or to any functions of Parent, which Child might
call) until Parent's constructor has been completed. Even though all bases
and members of Parent have been constructed once exceution of a constructors
body starts, that does not always gurantee that the object is in a well
defined state.

Think about (a poorly designed) class like

class Parent
{
int x;
Child* child;
...
public:
int GetX() const { return x; }
Parent()
{
child = new Child(this);
x = 0;
}
...
};

If Child's constructor would call Parent::GetX on its input object, it would
get some random value.

HTH
Heinz

Aug 12 '06 #2

P: n/a
On 11 Aug 2006 23:18:50 -0700, "craig" <cr**********@comcast.net>
wrote:
>During construction of an object "parent", if you create a subobject
that stores a pointer to the parent (through the "this" pointer), will
that pointer be valid when the subobject is later called?

class Parent
{
Parent::Parent() { child = new Child( this) };
Child *child;
};

class Child
{
Child::Child( Parent *par) { myParent = par };
Parent *myParent;
}

Will myParent be the correct address when child is subsequently
accessed?
Any comments greatly appreciated.
That's a common problem when you want to use back-pointers. Compilers
usually issue a warning. You may use it but it's unsafe for some cases
(see Heinz Ozwirk's post). For a really safe implementation you would
need some kind of 2-phase initialization (Child registers with Parent
when all constructor initialization is done). Alternatively you may
initialize child on demand and access it only with a get-function:

class Parent
{
// ...
Parent::Parent(): child(0) {};
Child* getChild() {
if (!child) {
child = new Child( this);
}
return child;
}
private:
Child *child;
};

The above is only possible when you use a pointer to Child as member
in Parent (which you usually try to avoid).

Best wishes,
Roland Pibinger
Aug 12 '06 #3

P: n/a
Thanks Roland, what you mention seems to be my problem,. because I can
correct it by initializing the back-pointer outside of the parent
constructor (after the construction is complete).

Originally the back-pointer that I created in the parent constructor
seemed like a valid pointer (in that it pointed to the right object),
but when one of the child members tried to access a parent variable
after one of the its variables had subsequently changed, the variable's
value was still at it's original (construction-time value). By setting
the back-pointer after the parent constructor completed, the
back-pointer was different, and would also reflect the updated parent
variable correctly.

-Craig

Roland Pibinger wrote:
On 11 Aug 2006 23:18:50 -0700, "craig" <cr**********@comcast.net>
wrote:
During construction of an object "parent", if you create a subobject
that stores a pointer to the parent (through the "this" pointer), will
that pointer be valid when the subobject is later called?

class Parent
{
Parent::Parent() { child = new Child( this) };
Child *child;
};

class Child
{
Child::Child( Parent *par) { myParent = par };
Parent *myParent;
}

Will myParent be the correct address when child is subsequently
accessed?
Any comments greatly appreciated.

That's a common problem when you want to use back-pointers. Compilers
usually issue a warning. You may use it but it's unsafe for some cases
(see Heinz Ozwirk's post). For a really safe implementation you would
need some kind of 2-phase initialization (Child registers with Parent
when all constructor initialization is done). Alternatively you may
initialize child on demand and access it only with a get-function:

class Parent
{
// ...
Parent::Parent(): child(0) {};
Child* getChild() {
if (!child) {
child = new Child( this);
}
return child;
}
private:
Child *child;
};

The above is only possible when you use a pointer to Child as member
in Parent (which you usually try to avoid).

Best wishes,
Roland Pibinger
Aug 12 '06 #4

P: n/a
Heinz,

Thanks so much for the helpful remarks. I learned a few things. It
seems like your remarks also explained my situation, but not sure. If
you have a moment, see my response to Roland where I explain the
behavior briefly.

Thanks again, craig
Heinz Ozwirk wrote:
"craig" <cr**********@comcast.netschrieb im Newsbeitrag
news:11**********************@i42g2000cwa.googlegr oups.com...
During construction of an object "parent", if you create a subobject
that stores a pointer to the parent (through the "this" pointer), will
that pointer be valid when the subobject is later called?

class Parent
{
Parent::Parent() { child = new Child( this) };
Child *child;
};

class Child
{
Child::Child( Parent *par) { myParent = par };
Parent *myParent;
}

Will myParent be the correct address when child is subsequently
accessed?

As long as your new instance of Child does only save a copy of the pointer
for later use, it is safe. If -- in Child's constructor -- it uses the
pointer to access data or non-static functions of its parent, that may
result in unexpected or even undefined behaviour.

Imagin there are other classes derived from Parent and Parent has virtual
functions. If Child's constructor calls one of these virtual functions, the
implementation provided by Parent intself will be called, never that of a
derived class. If it is a pure virtual function, you'll have a problem.

The Parent object passed to child might not be properly initialized. Any
initialization Parent's constructor does after create a new Child, will not
be visible to the Child (or to any functions of Parent, which Child might
call) until Parent's constructor has been completed. Even though all bases
and members of Parent have been constructed once exceution of a constructors
body starts, that does not always gurantee that the object is in a well
defined state.

Think about (a poorly designed) class like

class Parent
{
int x;
Child* child;
...
public:
int GetX() const { return x; }
Parent()
{
child = new Child(this);
x = 0;
}
...
};

If Child's constructor would call Parent::GetX on its input object, it would
get some random value.

HTH
Heinz
Aug 12 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.