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

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

Некоторый пример кода:

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

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

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

Большое спасибо!

127
задан Stephen 14 February 2013 в 17:30
поделиться

3 ответа

Это невозможно так, как вы описываете. Вам нужно будет добавить конструктор (может быть защищен) к базовому классу, чтобы пересылать его вместе. Примерно так:

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

    std::string something;
}

class Child : public Parent
{
private:
    Child() : Parent("Hello, World!")
    {
    }
}
121
ответ дан 24 November 2019 в 00:47
поделиться

Когда компилятор встречает список инициализаторов, объект производного класса еще не сформирован. Конструктор базового класса до сих пор не вызывался. Только после того, как был вызван конструктор базового класса, что-то возникает. Отсюда проблема. Если вы не вызываете конструктор базового класса явно, компилятор делает это за вас (путем создания соответствующего тривиального конструктора для базового класса). Это приводит к инициализации члена something по умолчанию.

Из проекта C ++ 0x:

12.6.2 Инициализация баз и членов

2 Имена в идентификаторе инициализатора памяти ищутся в области действия {{ 1}} класс конструктора и, если он не найден в этой области, ищется в области , содержащей определение конструктора . [Примечание: если класс конструктора содержит член с тем же именем, что и прямой или виртуальный базовый класс класса, mem-initializer- id, называющий член или базовый класс и состоящий из одного идентификатора , относится к члену класса. Идентификатор меминициализатора для скрытого базового класса может быть указано с использованием полного имени . —End note] Если mem-initializer-id не называет класс конструктора , нестатический член данных класса конструктора или {{1} } прямая или виртуальная база этого класса, mem-инициализатор неправильно сформирован.

Примечание: выделено мной.

63
ответ дан 24 November 2019 в 00:47
поделиться

Вы не можете инициализировать члены родительского класса в списке инициализации конструктора производного класса. Неважно, защищенные ли они, публичные или что-то еще.

В вашем примере член something является членом класса Parent , что означает, что он может быть инициализирован только в списке инициализаторов конструктора класса Parent .

12
ответ дан 24 November 2019 в 00:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: