class Bulk_quote : public Quote { //
Bulk_quote() = default;
Bulk_quote(const std::string&, double, std::size_t, double);
//
//
double net_price(std::size_t) const override;
private:
std::size_t min_qty = 0; //
double discount = 0.0; //
};
Класс Bulk_quote
унаследовал функцию isbn()
, а также переменные-члены bookNo
и price
из своего базового класса Quote
. Он определяет собственную версию функции net_price()
и имеет две дополнительные переменные-члена — min_qty
и discount
, которые определяют минимальное количество экземпляров и скидку, применяемую при его покупке.
Более подробная информация об используемых в списке наследования спецификаторах доступа приведена в разделе 15.5, а пока достаточно знать, что спецификатор доступа определяет, разрешено ли пользователям производного класса знать, что он унаследован от базового класса.
При открытом наследовании открытые члены базового класса становятся частью интерфейса производного. Кроме того, объект открытого производного типа можно привязать к указателю или ссылке на базовый тип. Поскольку в списке наследования использован спецификатор public
, интерфейс класса Bulk_quote
неявно содержит функцию isbn()
, объект класса Bulk_quote
можно использовать там, где ожидается указатель или ссылка на объект класса Quote
.
Большинство классов непосредственно происходит только от одного базового класса. Эта форма наследования, известная как "одиночное наследование", и является темой данной главы. В разделе 18.3 будут описаны классы, у которых в списке наследования больше одного базового класса.
Производные классы часто, но не всегда, переопределяют унаследованные виртуальные функции. Если производный класс не переопределяет виртуальную функцию своего базового класса, то, подобно любому другому члену, производный класс наследует версию, определенную в его базовом классе.
virtual
, но не обязательно. По причинам, рассматриваемым в разделе 15.3, новый стандарт позволяет производному классу явно указывать, что функция-член предназначена для переопределения унаследованной виртуальной функции. Для этого применяется спецификатор override
в определении после списка параметров, либо после ключевого слова const
, либо квалификатора ссылки, если член класса константен (см. раздел 7.1.2), или ссылки на функцию (см. раздел 13.6.3).
Объект производного класса состоит из несколькими частей: нестатических членов, определенных в самом производном классе, а также объекта, состоящего из нестатических членов каждого его базового класса, от которых он происходит. Таким образом, объект класса Bulk_quote
будет содержать четыре части данных: переменные-члены bookNo
и price
, унаследованные от класса Quote
, и переменные-члены min_qty
и discount, определенные в классе Bulk_quote
.
Хотя стандарт не определяет расположение в памяти производных объектов, объект Bulk_quote
можно считать состоящим из двух частей (рис. 15.1).
Рис. 15.1. Концептуальная структура объекта класса Bulk_quote
Поскольку производная часть объекта соответствует его базовому классу (классам), объект производного типа можно использовать так, как будто это объект его базового класса (классов). В частности, ссылку или указатель на базовый класс можно связать с частью базового класса производного объекта.
Quote item; //
Bulk_quote bulk; //
Quote *p = &item //
p = &bulk //
Quote &r = bulk; //
Это преобразование обычно называют