Факт неявного преобразования производного в базовый означает возможность использования объекта производного типа или ссылки на него там, где нужна ссылка на базовый тип. Точно так же можно использовать указатель на производный тип там, где требуется указатель на базовый тип.

Факт наличия в объекте производного класса частей объектов его базовых классов является основой работы наследования.

Конструкторы производного класса

Хотя объект производного класса содержит члены, унаследованные им от базового, он не может инициализировать их непосредственно. Как и любой другой код, создающий объект базового класса, производный класс должен использовать конструктор базового класса для инициализации своей части базового класса.

Каждый класс сам контролирует инициализацию своих членов.

Часть базового класса объекта, наряду с переменными-членами производного класса, инициализируется на этапе инициализации конструктора (см. раздел 7.5.1). Аналогично инициализации переменных-членов, для передачи аргументов конструктору базового класса конструктор производного класса использует свой список инициализации. Рассмотрим конструктор Bulk_quote() с четырьмя параметрами:

Bulk_quote(const std::string& book, double p,

           std::size_t qty, double disc) :

 Quote(book, p), min_qty(qty), discount(disc) { }

 // как прежде

};

Для инициализации переменных-членов конструктору класса Quote передаются его первые два параметра (представляющие ISBN и цену). Этот конструктор инициализирует базовую часть класса Bulk_quote (т.е. переменные-члены bookNo и price). Когда (пустое) тело конструктора класса Quote закончит работу, часть базового класса создаваемого объекта будет инициализирована. Затем инициализируются прямые переменные-члены min_qty и discount. И наконец, выполняется (пустое) тело конструктора класса Bulk_quote.

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

Сначала инициализируются члены базового класса, а затем члены производного класса в порядке их объявления.

Использование членов базового класса из производного

Производный класс может обращаться к открытым и защищенным членам своего базового класса:

// если приобретено достаточное количество экземпляров,

// использовать цену со скидкой

double Bulk_quote::net_price(size_t cnt) const {

 if (cnt >= min_qty)

  return cnt * (1 - discount) * price;

 else

  return cnt * price;

}

Эта функция вычисляет цену со скидкой: если приобретенное количество экземпляров превышает значение переменной min_qty, к цене (price) применяется скидка (discount).

Более подробная информация об областях видимости приведена в разделе 15.6, а пока достаточно знать, что область видимости производного класса вкладывается в область видимости его базового класса. В результате нет никакого различия между тем, как член производного класса использует члены, определенные в его собственном классе (например, min_qty и discount), и как он использует члены, определенные в его базовом классе (например, price).

Перейти на страницу:

Похожие книги