Подтвердить что ты не робот

С++: Инициализация наследуемого поля

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

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 in B (поскольку родительские конструкторы выполняются до инициализации элемента унаследованного класса). Где ошибка в моих рассуждениях? Что действительно происходит в этом коде?

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

4b9b3361

Ответ 1

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

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

Ответ 2

Что вы хотите, так это:

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

так что m_int инициализируется в правильном месте.

Edit:

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

Ответ 3

Чтобы создать экземпляр класса 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

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