views:

619

answers:

3

Is it possible to use the initialization list of a child class' constructor to initialize data members declared as protected in the parent class? I can't get it to work. I can work around it, but it would be nice if I didn't have to.

Some sample code:

class Parent
{
protected:
    std::string something;
}

class Child : public Parent
{
private:
    Child() : something("Hello, World!")
    {
    }
}

When I try this, the compiler tells me: "class 'Child' does not have any field named 'something'". Is something like this possible? If so, what is the syntax?

Many thanks!

+16  A: 
Phil Nash
+1. Beat me to it.
Fred Larson
hehe, everyone has to be "fastest gun" sometimes ;-)
Phil Nash
This is exactly the workaround I'd already come up with. At least now I don't have to worry about whether or not it can be done. :)
Skinniest Man
+1  A: 

You can't initialize members of the parent class in the derived class constructor initialization list. It doesn't matter wherther they are protected, public or anything else.

In your example, member something is member of Parent class, which means that it can only be initialized in the constructor initializer list of Parent class.

AndreyT
+7  A: 

When the compiler comes across the initializer list, the derived class object is yet to be formed. The base class ctor has not been called till then. Only after the base class ctor has been called, something comes to being. Hence the problem. When you do not call the base class ctor explicitly, the compiler does that for you (by generating the appropriate trivial ctor for the base class). This causes the something member to be default initialized.

From C++0x draft:

12.6.2 Initializing bases and members

2 Names in a mem-initializer-id are looked up in the scope of the constructor’s class and, if not found in that scope, are looked up in the scope containing the constructor’s definition. [ Note: if the constructor’s class contains a member with the same name as a direct or virtual base class of the class, a mem-initializer-id naming the member or base class and composed of a single identifier refers to the class member. A meminitializer- id for the hidden base class may be specified using a qualified name. —end note ] Unless the mem-initializer-id names the constructor’s class, a non-static data member of the constructor’s class or a direct or virtual base of that class, the mem-initializer is ill-formed.

Note: Emphasis mine.

dirkgently
Thanks for pointing me at the "why". Makes total sense. I've been away from C++ for too long... :)
Skinniest Man