Initialization with this.

M

Morya

Hi,

I had a scenario where classes had two way composition (Already
present in a huge code. Wasn't introduced by me) something like this:

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

B {
public B (A aobj) : a(aobj) {}
private:
A a;
};

I believe this code is not valid (undefined behavior ??) as A is not
fully constructed when it is passed to B. I googled around but didn't
find a direct reference of such situation. Any hints? pointers ?

~Moh
 
R

red floyd

Morya said:
Hi,

I had a scenario where classes had two way composition (Already
present in a huge code. Wasn't introduced by me) something like this:

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

B {
public B (A aobj) : a(aobj) {}
private:
A a;
};

I believe this code is not valid (undefined behavior ??) as A is not
fully constructed when it is passed to B. I googled around but didn't
find a direct reference of such situation. Any hints? pointers ?

To heck with UB. How the hell does it even compile? B is not defined
when it is declared as a member variable of A.
 
M

Morya

To heck with UB.  How the hell does it even compile?  B is not defined
when it is declared as a member variable of A.

Sorry for misleading code. you could use pointer and forward declare a
class. something like this:

class B;

class A {
..
...
private:
B* b;
};

The main point here about the state of the object which is passed with
the this pointer.
I would accept code any code you suggest that would convey the same
idea. The code that i presented was a place holder.
 
Z

zr

Hi,

I had a scenario where classes had two way composition (Already
present in a huge code. Wasn't introduced by me) something like this:

A {
public:
A ()
: b(*this)
{}

private:
B b;

};

B {
public B (A aobj) : a(aobj) {}
private:
A a;

};

I believe this code is not valid  (undefined behavior ??) as A  is not
fully constructed when it is passed to B. I googled around but didn't
find a direct reference of such situation. Any hints? pointers ?

~Moh

I don't know what is the expected behavior of the above code, if any.
But if you are looking for a solution to your problem, you might
consider changing class B's member a to be of type A& or A*. That way
a would refer/point to the right object. Of course, this solution may
not be practical if B must have its private copy of the A stored in a.

Here's the reference option (similarly you could write the pointer
option):

A {
public:
A ()
: b(*this)
{}

private:
B b;

};

B {
public B (A& aobj) : a(aobj) {}
private:
A& a; // a is now a reference

};
 
M

Marcel Müller

Hi!
Sorry for misleading code. you could use pointer and forward declare a
class. something like this:

class B;

class A {
..
..
private:
B* b;
};

The main point here about the state of the object which is passed with
the this pointer.
I would accept code any code you suggest that would convey the same
idea. The code that i presented was a place holder.

It depends on what you are doing with the A instance.
Storing Pointers and references to *this is valid at any time in the
constructor. Calling member functions may be or may be not.
Effectively everything you invoke from a constructor becomes part of the
constructor. This applies to your own member functions in the same way
as for any other piece of code. The constructor is responsible to do
this in a well defined way. At least all base classes and members of A
are initialized at this point (unless you forgot to initialize som POD
types).


Marcel
 
K

Kai-Uwe Bux

Morya said:
Sorry for misleading code. you could use pointer and forward declare a
class. something like this:

class B;

class A {
..
..
private:
B* b;
};

Now you left out the part about the initialization of the member b. If you
want

A ()
: b ( new B (*this) )
{}

then B would have to be complete again. For only initializing a pointer,
though, it is hard to see how an A object could be used.

The main point here about the state of the object which is passed with
the this pointer.

The first point is to come up with a compilable example. Only then can the
question about undefined behavior be asked meaningfully.
I would accept code any code you suggest that would convey the same
idea. The code that i presented was a place holder.

I would prefer if you could provide code. Everything we can do amounts to
guesswork.


Best

Kai-Uwe Bux
 
M

Morya

The main point here about the state of the object which is passed with
The first point is to come up with a compilable example. Only then can the
question about undefined behavior be asked meaningfully.

Agreed. Was trying to build one out of the huge hierarchy already
present. Essentially, ended up butchering the concept!! My Apologies.
I would prefer if you could provide code. Everything we can do amounts to
guesswork.
Agreed.

Best

Kai-Uwe Bux

The current case was about initialization of a pointer, which would be
used latter. To summarize the code would look like:

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

class A {
public:
A(): b(new B(this)) {}
private:
B* b;
};

As pointed out by Marcel Müller, this should be okay. Although lesson
learnt is that it might not be safe to dereference it.

Thanks,
Mo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top