C ++: инициализация унаследованного поля - PullRequest
20 голосов
/ 21 октября 2010

У меня вопрос об инициализации унаследованных членов в конструкторе производного класса.Пример кода:

class A
    {
public:
    int m_int;
    };

class B: public A
    {
public:
    B():m_int(0){}
    };

Этот код дает мне следующий вывод:

In constructor 'B::B()': Line 10: error: class 'B' does not have any field named 'm_int'

(см. http://codepad.org/tn1weFFP)

Я предполагаюпочему это происходит? m_int должен быть членом B, а родительский класс A уже должен быть инициализирован, когда происходит инициализация m_int в B (поскольку родительские конструкторы выполняются до инициализации члена унаследованного класса).ошибка в моих рассуждениях? Что на самом деле происходит в этом коде?

EDIT: мне известны другие возможности инициализации этого члена (базовый конструктор или присваивание в производном конструкторе), но я хочупонять, почему это незаконно в том, как я это пробую? Какая-то особенная особенность языка C ++ или такая? Пожалуйста, укажите мне параграф в стандарте C ++, если это возможно.

Ответы [ 4 ]

21 голосов
/ 21 октября 2010

Вам нужно создать конструктор для A (он может быть защищен, так что только B может вызывать его), который инициализирует m_int так же, как вы, затем вызываете :A(0), где у вас есть :m_int(0)

Youтакже можно просто установить m_int = 0 в теле конструктора B.Он доступен (как вы описываете), но не доступен в специальном синтаксисе конструктора.

4 голосов
/ 21 октября 2010

Чтобы создать экземпляр класса B, сначала необходимо создать экземпляр класса A.Во время этого экземпляра m_int инициализируется.После этой инициализации вызывается конструктор b, поэтому вы не можете повторно инициализировать m_int.Если это ваша цель, вы можете реализовать конструктор для A, который принимает int, а затем вызвать его в списке инициализации B:

class A
{
public:
  A(int x): m_int(x) {}
  int m_int;
};

class B: public A
{
public:
  B(): A(2) {}
};
4 голосов
/ 21 октября 2010

То, что вы хотите, это:

class A{
public:
    A() : m_int(0);
    int m_int;
};

, чтобы m_int инициализировался в правильном месте.

Редактировать:

Из комментария вышеПричина, по которой компилятор жалуется при попытке инициализировать переменную m_int в B, заключается в том, что она уже была инициализирована конструктором A.То есть вы не можете повторно инициализировать что-либо, только переназначить.Таким образом, вы можете переназначить, как сказал Бен Джексон, или инициализировать в нужном месте.

0 голосов
/ 05 мая 2017

создайте конструктор в A и используйте B (): A (2) {} застраховано от B (): m_int (0) {} его работа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...