473,473 Members | 1,755 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

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

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
4 4137
"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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: stub | last post by:
Some questions about "this" pointer: 1. To make an assignment function, Stribg &String::operator=(const String &other) { ... return *this; }
3
by: Eric Chaves | last post by:
Hi fellows, According to the C# language specification (10.5.3), Every virtual method has a "most derived implementation" determined by a 3-step rule. If I invoke the virtual method from a normal...
3
by: Polaris | last post by:
I noticed in the ASP.NET web application, as shown below, the "this" pointer is used in the code generated by the Visual C# IDE. Anyone can explain why it is necessary to use the "this" pointer...
6
by: ZRexRider | last post by:
I've been reading the newsgroups and most of the solutions for this message are simple and obvious but unfortunately don't solve my problem. I have an MS-Access 2002 ADP application that...
8
by: solarin | last post by:
Hi all. I'm writting a logger class to write all the debug/info/warning/error messages in a file. Every time a class needs to send any message, should send a code (int) and a message (string)....
0
by: john | last post by:
Hey, I'am confused on the principles on checking a assingment operators using This pointer. I understand using *this to access data member in a class. const B &operator=(const B& x){ if...
10
by: Angel Tsankov | last post by:
Hello! Is the following code illformed or does it yield undefined behaviour: class a {}; class b {
8
by: =?Utf-8?B?VHJlY2l1cw==?= | last post by:
Hello, Newsgroupians: I have a large class with a lot of member variables. I also have a function in the class that I would like to change ALL Of the member variables. I am trying to assign...
6
by: babakandme | last post by:
Hi to every body...:D I'm a novice C++ programmer & I've a question, I have the ClassA & in it's constructor, I instantiate ClassB, and I want send "this" pointer """pointer to ClassA""" to the...
2
by: Sergei Shelukhin | last post by:
Hi. I have barely written any C++ for past 3-4 years, I need to refresh it in my memory so I decided to do some coding starting with classic algos and data structures, using Visual Studio 9,...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.