1

I have following simple code:

#include <iostream>
#include <vector>

template <class Derived>
struct Base
{
    Base()
    {
        static_cast<Derived*>(this)->foo(); 
    }

    std::vector<int> m_ints;
};

struct Derived : Base<Derived>
{
    Derived() : Base() 
    {
        std::cout << a;
    }

    void foo()
    {
        m_ints.push_back(37);
        a = 4;
    }

    int a;
};

int main() 
{
    Derived d;
    return 0;
}

I know about order of calling constructors when object is created. Constructor are called from the "most base -> down". So At the Base constructor Derived object is not fully constructed.

1) Is it safe, to call Derived::foo in Base constructor, when Derived::foo do no touch Derived object? I mean, when there is no such line as a = 4, just touching Base object.

2) If I run posted code, it really works, although I'm touching a which should not exist at that time. Is it guarantee to work? (I tested it on VS2013, VS2010, and GCC 4.8.1 on Ideone)

relaxxx
  • 7,566
  • 8
  • 37
  • 64

1 Answers1

0

It will work in this specific case, but I would advise not to do this. Subtle changes in the code might suddenly break the logic (e.g. someone making the method foo virtual, someone initializing data member a in the constructor or Derived, ...).

If the base class needs information from a derived class, then the derived class must pass that information to the constructor of the base class. In this class, the value 37 should be passed from the constructor of Derived to the constructor of Base.

And when data member a must be initialized, initialize it in the constructor of Derived, not somewhere else.

EDIT: In C++11, if the Derived class wants to inject code in the constructor of Base, it can pass a lambda to Base. Base then simply executes the lambda in its constructor.

Patrick
  • 23,217
  • 12
  • 67
  • 130
  • thank you for your answer. Can you please provide additional info how to pass lambda from Derive do Base to be able invoke lambda in Base constructor? And in real case scenario, Derive has several constructors and I don't want to pass lambda in every one. Is there another way? – relaxxx Mar 27 '14 at 09:18