Логика конструктора при наследовании

390
30 декабря 2017, 04:03

Почему логика языка С++ позволяет производному классу пользоваться конструктором БЕЗ параметров базового класса, НО НЕ позволяет пользоваться конструктором с параметрами базового класса? Нужно создавать отдельный конструктор с параметрами для производного.

class Base    // базовый класс
{
public:
    Base() { }
    Base(int input) {}
};
class Derived : public Base  // производный класс
{
public:
    Derived() : Base () { }  // конструктор производного класса вызывает конструктор базового
    Derived(int inputD) : Base(inputD) { } // inputD передается в конструктор с параметром класса Base
};
int main()
{
    Base base(3);     // объект базового класса
    Derived der(4);   // объект производного класса
}

При создании конструктора производного класса использовали другой параметр. ЗАЧЕМ?

Answer 1

Если базовый класс имеет конструктор без параметров, то он будет вызван неявно из конструктора производного класса. Т.е. писать что-то вроде Derived() : Base() { } не требуется.

Если же из конструктора производного класса (не важно, с параметрами или без) нужно вызывать конструктор базового класса, принимающий параметры, то требуется явно указать какие это будут параметры, т.е. прокидывания аргумента из конструктора производного класса в конструктор базового класса в виде один-к-одному по умолчанию нет, нужно написать это руками.

Derived(int i) : Base(i) { }

Всё это сделано для того, чтобы было ясно видно как трансформируется параметр. Ведь вполне может потребоваться и такая запись:

Derived(int i) : Base(f(i)) { }

где f() - некоторая функция преобразования, которая в общем случае может порождать тип, отличный от int, т.к. конструктор Base вполне может иметь версию с параметром другого типа. Пример:

Base(const char* c) {}
Derived(int i) : Base(itoa(i))

Также в с++11 появилась возможность наследования конструкторов для достижения эффекта сквозной передачи параметров. Таким образом вместо:

Derived(int i) : Base(i) { }

можно написать следующее:

using Base::Base;

Этой записью осуществляется прокидывание имеющихся сигнатур конструкторов базового класса в производный.

READ ALSO
Потоковая передача видео на сервер

Потоковая передача видео на сервер

ЗдравствуйтеПрошарил весь гугл, но так и не понял даже в какую сторону идти

239
из римских в десятичные

из римских в десятичные

Делаю конвертер из римских цифр в десятичные и вот который час танцую с бубном перед ошибкой, но как то никак

225
Android.Java.Sqlite.Не находит столбец в таблице

Android.Java.Sqlite.Не находит столбец в таблице

Не находит столбец в таблице и выдаёт такую ошибку :

249
Карта интенсивностей (heatmap) в Java

Карта интенсивностей (heatmap) в Java

Есть двумерный массив с double значениямиНа основании этого массива нужно построить карту интенсивностей (heatmap)

170