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