Действительно ли возможно использовать список инициализации конструктора дочернего класса для инициализации элементов данных, объявленных, как защищено в родительском классе? Я не могу заставить это работать. Я могу работать вокруг этого, но было бы хорошо, если бы я не имел к.
Некоторый пример кода:
class Parent
{
protected:
std::string something;
};
class Child : public Parent
{
private:
Child() : something("Hello, World!")
{
}
};
Когда я пробую это, компилятор говорит мне: "класс 'Ребенок' не имеет никакого поля названным 'чем-то'". Действительно ли что-то вроде этого возможно? Если так, каков синтаксис?
Большое спасибо!
Это невозможно так, как вы описываете. Вам нужно будет добавить конструктор (может быть защищен) к базовому классу, чтобы пересылать его вместе. Примерно так:
class Parent
{
protected:
Parent( const std::string& something ) : something( something )
{}
std::string something;
}
class Child : public Parent
{
private:
Child() : Parent("Hello, World!")
{
}
}
Когда компилятор встречает список инициализаторов, объект производного класса еще не сформирован. Конструктор базового класса до сих пор не вызывался. Только после того, как был вызван конструктор базового класса, что-то
возникает. Отсюда проблема. Если вы не вызываете конструктор базового класса явно, компилятор делает это за вас (путем создания соответствующего тривиального конструктора для базового класса). Это приводит к инициализации члена something
по умолчанию.
Из проекта C ++ 0x:
12.6.2 Инициализация баз и членов
2 Имена в идентификаторе инициализатора памяти ищутся в области действия {{ 1}} класс конструктора и, если он не найден в этой области, ищется в области , содержащей определение конструктора . [Примечание: если класс конструктора содержит член с тем же именем, что и прямой или виртуальный базовый класс класса, mem-initializer- id, называющий член или базовый класс и состоящий из одного идентификатора , относится к члену класса. Идентификатор меминициализатора для скрытого базового класса может быть указано с использованием полного имени . —End note] Если mem-initializer-id не называет класс конструктора , нестатический член данных класса конструктора или {{1} } прямая или виртуальная база этого класса, mem-инициализатор неправильно сформирован.
Примечание: выделено мной.
Вы не можете инициализировать члены родительского класса в списке инициализации конструктора производного класса. Неважно, защищенные ли они, публичные или что-то еще.
В вашем примере член something
является членом класса Parent
, что означает, что он может быть инициализирован только в списке инициализаторов конструктора класса Parent
.