Initialization with this.

Discussion in 'C++' started by Morya, Nov 10, 2008.

  1. Morya

    Morya Guest

    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
    Morya, Nov 10, 2008
    #1
    1. Advertising

  2. Morya

    red floyd Guest

    Morya wrote:
    > 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.
    red floyd, Nov 10, 2008
    #2
    1. Advertising

  3. Morya

    Morya Guest

    > 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.
    Morya, Nov 10, 2008
    #3
  4. Morya

    zr Guest

    On Nov 10, 8:03 am, Morya <> wrote:
    > 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

    };
    zr, Nov 10, 2008
    #4
  5. Hi!

    Morya schrieb:
    >> 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.


    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
    Marcel Müller, Nov 10, 2008
    #5
  6. Morya

    Kai-Uwe Bux Guest

    Morya wrote:

    >> 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;
    > };


    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
    Kai-Uwe Bux, Nov 10, 2008
    #6
  7. Morya

    Morya Guest

    > > 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.


    Agreed. Was trying to build one out of the huge hierarchy already
    present. Essentially, ended up butchering the concept!! My Apologies.
    >
    > > 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.


    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
    Morya, Nov 10, 2008
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JKop
    Replies:
    10
    Views:
    937
  2. Matthias Kaeppler
    Replies:
    2
    Views:
    437
    Victor Bazarov
    Jul 18, 2005
  3. Replies:
    6
    Views:
    458
    Ron Natalie
    Dec 11, 2005
  4. toton
    Replies:
    5
    Views:
    932
    Victor Bazarov
    Sep 28, 2006
  5. Jess
    Replies:
    23
    Views:
    926
Loading...

Share This Page