1
#include <iostream>

class FooParent
{
    public:
        FooParent(int* new_p_bar)
        {
            p_bar = new_p_bar;
        }
    public:
        int* p_bar;
};

class FooChild : public FooParent
{
    public:
        int bar;
    public:
        FooChild(int new_x)
        :FooParent(&bar)
        ,bar(new_x) \\ point of concern
            {} 
};

int main()
{ 
    FooChild foo(8);
    std::cout << foo.bar << std::endl;

}

The above example works as I want it to .i.e. link the pointer p_bar to bar. However, my concern is that I am pointing to a member whose constructor is not yet called.

Is this code valid, or does the standard have something to say about it. If not what is the alternative.

NOTE: In my application bar is an Object Bar (not int), does this have any implications?

aiao
  • 4,621
  • 3
  • 25
  • 47
  • The constructor will have been called. The order in the initializer list is not the same as the order of construction. Member variables are initialized in the order of declaration in the class. – Roger Rowland Mar 13 '13 at 12:09
  • if `FooParent`'s c-tor only stores address of `Bar`, and there's no other initializations between `FooParent(&bar)` and `bar(new_x)` then it seems, that there's no problems here – borisbn Mar 13 '13 at 12:09
  • 4
    In other words, it will work only with **pointer** (or reference). Not with object's copy – borisbn Mar 13 '13 at 12:14
  • @borisbn so if I want to use this, I will have to implement the copy constructor (and copy assignment operator) to take this into account. Is that right? – aiao Mar 13 '13 at 12:54
  • 1
    Nope. Neither copy c-tor nor assignment operator would help with it. It will work only with pointer (or reference) – borisbn Mar 13 '13 at 12:56
  • @barisbn then I don't understand. Could you please post a complete answer of what you mean. – aiao Mar 13 '13 at 12:59
  • Look at [this](http://liveworkspace.org/code/42dhJ3$4). I mean that if `FooParent`'s constructor **only stores a pointer** to external `int` (or `Bar` - doesn't matter) then there will be no problem. In other hand, if you'll give a **copy** of bar to `FooParent` - like [this](http://liveworkspace.org/code/42dhJ3$5) - this will not work. Even if `Bar` will have a copy c-tor or/and assignment operator – borisbn Mar 13 '13 at 13:35
  • @aiao read about base-from-member idiom, there is total description of problem of your code. The problem is that *you are passing reference to yet uninitialized object, which is full of garbage and may cause segfault if you will use it* – kassak Mar 13 '13 at 13:38

2 Answers2

2

If you are passing pointer to member there is no undefined behavior, until you are trying to dereference it. If you want to have constructor called look into base-from-member idiom http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Base-from-Member

kassak
  • 3,974
  • 1
  • 25
  • 36
0

Look at this:

class FooParent {
    public:
        FooParent(int* new_p_bar)
        {
            p_bar = new_p_bar;
            *p_bar = 99; // this has no sense
        }
        void set99() {
            *p_bar = 99; // this - has
        }
    public:
        int* p_bar;
};

class FooChild : public FooParent
{
    public:
        int bar;
    public:
        FooChild(int new_x)
        :FooParent(&bar)
        ,bar(new_x) // point of concern
            {} 
};

int main()
{ 
    FooChild foo( 42 );
    std::cout << foo.bar << std::endl;
    foo.set99();
    std::cout << foo.bar << std::endl;
}

LWS.

I mean that if FooParent's constructor only stores a pointer to external int (or Bar - doesn't matter) then there will be no problem.

In other hand, if you'll give a copy of bar to FooParent - like this

class FooParent
{
    public:
        FooParent(Bar new_p_bar)
        {
            p_bar = new_p_bar;
        }
        void set99() {
            p_bar = 99; // this - has
        }
    public:
        Bar p_bar;
};

class FooChild : public FooParent
{
    public:
        Bar bar;
    public:
        FooChild(Bar new_x)
        :FooParent(bar)
        ,bar(new_x) // point of concern
            {} 
};

int main()
{ 
    FooChild foo( 42 );
    std::cout << foo.bar << std::endl;
    foo.set99();
    std::cout << foo.bar << std::endl;
}

LWS.

this will not work. Even if Bar will have a copy c-tor or/and assignment operator

borisbn
  • 4,988
  • 25
  • 42
  • I am talking about copy c-tor and copy assign for `FooChild` so that when it copies `FooChild` it assigns `p_bar` to the newly copied `Bar`. Would that be good enough? – aiao Mar 14 '13 at 10:43
  • Oah... Sorry. I thought aboud copy c-tor of `Bar`... I can't see any problem if "it assigns `p_bar` to the newly copied `Bar`" – borisbn Mar 14 '13 at 11:15