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