Почему мне нужно установить переменную в какое-то значение в базовом классе, когда я объявляю производный класс?

Я не понимаю, почему, когда я пытаюсь создать объект базового класса, я могу, но только без объявления производного класса, а при объявлении Derived мне нужно установить значение аргумента «= 0» в конструкторе базового класса?

#include <cstdlib>

using namespace std;

class Base {
   public:
       int m_nValue;

       Base(int nValue=0) //<--- why here i need = 0 ?
           : m_nValue(nValue)
       {}
};

class Derived: public Base {
public:
    double m_dValue;

    Derived(double dValue) 
        : m_dValue(dValue)
    {}
};


int main(int argc, char** argv) {
  Base cBase(5); // use Base(int) constructor
  return 0;
}

person BabaMara    schedule 26.02.2016    source источник


Ответы (2)


Нет, не знаешь. Проблема в том, что когда вы создаете подкласс, вы никогда не даете никакого значения ctor базового класса, что-то вроде этого:

Derived(double dValue) : Base(0), m_dValue(dValue) {}

Таким образом, компилятор смотрит на базовый класс и ищет либо: ctor без аргументов, либо ctor со значениями по умолчанию (он не смотрит на ctor по умолчанию, поскольку определение ctor удаляет ctor по умолчанию). Либо:

class Base {
public:    
    int m_nValue;   
    Base() : m_nValue(0) {}
    Base(int nValue) : m_nValue(nValue) {}
};

or

class Base {
public:    
    int m_nValue;   
    Base(int nValue=0) : m_nValue(nValue) {}
};
person Jean-Baptiste Yunès    schedule 26.02.2016

Base(int nValue = 0) также будет действовать как конструктор по умолчанию, поскольку для nValue было предоставлено значение по умолчанию. В настоящее время ваш конструктор Derived будет вызывать этот конструктор неявно, а nValue установлено в 0.

Формально вам не нужно этого делать, но это будет означать, что пользователь вашего класса должен указать явное значение для nValue и вам придется написать конструктор по умолчанию. Вы можете добиться последнего, написав Base() = default;, хотя тогда элемент m_nValue не будет инициализирован, если вы не используете фигурные скобки C++11 (например, Base b{};). (Обратите внимание, что поведение при чтении неинициализированной переменной не определено.)

person Bathsheba    schedule 26.02.2016
comment
Я думаю, что запись Base() = default означает, что конструктор по умолчанию не будет инициализировать m_nValue, что было бы плохо. - person Martin Bonner supports Monica; 26.02.2016