Инициализация защищенных членов родителя с помощью списка инициализации (C ++) - PullRequest
122 голосов
/ 18 февраля 2010

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

Пример кода:

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

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

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

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

Ответы [ 4 ]

115 голосов
/ 18 февраля 2010

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

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

    std::string something;
}

class Child : public Parent
{
private:
    Child() : Parent("Hello, World!")
    {
    }
}
61 голосов
/ 18 февраля 2010

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

Из C ++ 0x черновик:

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

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

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

12 голосов
/ 18 февраля 2010

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

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

0 голосов
/ 27 апреля 2017

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

class Parent
{

protected:
std::string something;
};

class Child : public Parent
{

private:
using Parent::something;
Child()
{
    something="Hello, World!";
}
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...