Initialize parent's protected members with initialization list (C++)

C++InheritanceConstructorInitialization List

C++ Problem Overview


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!

C++ Solutions


Solution 1 - C++

It is not possible in the way you describe. You'll have to add a constructor (could be protected) to the base class to forward it along. Something like:

class Parent
{
protected:
Parent( const std::string& something ) : something( something )
{}



std::string something;




}




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

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

Solution 2 - C++

When the compiler comes across the initializer list, the derived class object is yet to be formed. The base class constructor has not been called till then. Only after the base class constructor has been called, something comes to being. Hence the problem. When you do not call the base class constructor explicitly, the compiler does that for you (by generating the appropriate trivial constructor 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.

Solution 3 - C++

You can't initialize members of the parent class in the derived class constructor initialization list. It doesn't matter whether 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.

Solution 4 - C++

As @philsquared said, you can't initialize a parent class' members from the child's member initialization list, but you can add a parent class constructor, and call this constructor from the child's member initialization list.

And as @dirkgently said, the reason you can't initialize the parent class' members in the initialization list is because at this point, the parent class constructor hasn't been called yet, so these fields are not available.

For posterity, I also wanted to point out that if you don't want to write a constructor for your parent class, you can just initialize the protected members in the body of the constructor:

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

Solution 5 - C++

Maybe you can try it in that way using the keyword "using"

class Parent
{

protected:
std::string something;
};

class Child : public Parent
{

private:
using Parent::something;
Child()
{
    something="Hello, World!";
}
};

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStephenView Question on Stackoverflow
Solution 1 - C++philsquaredView Answer on Stackoverflow
Solution 2 - C++dirkgentlyView Answer on Stackoverflow
Solution 3 - C++AnTView Answer on Stackoverflow
Solution 4 - C++Daniel C JacobsView Answer on Stackoverflow
Solution 5 - C++user7710359View Answer on Stackoverflow