Инициализация защищенных родительских элементов с помощью списка инициализации (C++)


можно ли использовать список инициализации конструктора дочернего класса для инициализации элементов данных, объявленных защищенными в родительском классе? Я не могу заставить его работать. Я могу обойти это, но было бы неплохо, если бы мне не пришлось.

пример кода:

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

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

когда я пытаюсь это сделать, компилятор говорит мне:"класс 'Child' не имеет никакого поля с именем 'something'". Возможно ли что-то подобное? Если да, то каков синтаксис?

много спасибо!

4 115

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 класса.

может быть, вы можете попробовать это таким образом, используя ключевое слово "using"

class Parent
{

protected:
std::string something;
};

class Child : public Parent
{

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