Стенли Липпман - Язык программирования C++. Пятое издание
- Название:Язык программирования C++. Пятое издание
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2014
- Город:Москва
- ISBN:978-5-8459-1839-0
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стенли Липпман - Язык программирования C++. Пятое издание краткое содержание
Вы держите в руках новое издание популярного и исчерпывающего бестселлера по языку программирования С++, которое было полностью пересмотрено и обновлено под
. Оно поможет вам быстро изучить язык и использовать его весьма эффективными и передовыми способами. В соответствии с самыми передовыми и современными методиками изложения материала авторы демонстрируют использование базового языка и его стандартной библиотеки для разработки эффективного, читабельного и мощного кода.
С самого начала этой книги читатель знакомится со стандартной библиотекой С++, ее самыми популярными функциями и средствами, что позволяет сразу же приступить к написанию полезных программ, еще не овладев всеми нюансами языка. Большинство примеров из книги было пересмотрено так, чтобы использовать новые средства языка и продемонстрировать их наилучшие способы применения. Эта книга — не только проверенное руководство для новичков в С++, она содержит также авторитетное обсуждение базовых концепций и методик языка С++ и является ценным ресурсом для опытных программистов, особенно желающих побыстрей узнать об усовершенствованиях С++11.
Стенли Б. Липпман Жози Лажойе Барбара Э. Му • Узнайте, как использовать новые средства языка С++11 и стандартной библиотеки для быстрого создания надежных программ, а также ознакомьтесь с высокоуровневым программированием
• Учитесь на примерах, в которых показаны передовые стили программирования и методики проектирования
• Изучите принципы и узнайте почему язык С++11 работает именно так
• Воспользуйтесь множеством перекрестных ссылок, способных помочь вам объединить взаимосвязанные концепции и проникнуть в суть
• Ознакомьтесь с современными методиками обучения и извлеките пользу из упражнений, в которых подчеркиваются ключевые моменты, позволяющие избежать проблем
• Освойте лучшие методики программирования и закрепите на практике изученный материал
Исходный код примеров можно загрузить с веб-страницы книги на сайте издательства по адресу: http://www.williamspublishing.com
Язык программирования C++. Пятое издание - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
15.7. Конструкторы и функции управления копированием
Подобно любому другому классу, класс в иерархии наследования контролирует происходящее при создании, копировании, перемещении, присвоении или удалении объектов его типа. Как и у любого другого класса, если класс (базовый или производный) сам не определяет одну из функций управления копированием, ее синтезирует компилятор. Кроме того, как обычно, синтезируемая версия любой из этих функций-членов может быть удаленной функцией.
15.7.1. Виртуальные деструкторы
Основное воздействие, которое наследование оказывает на управление копированием для базового класса, заключается в том, что базовый класс обычно должен определять виртуальный деструктор (см. раздел 15.2.1). Деструктор должен быть виртуальной функцией, чтобы обеспечить объектам в иерархии наследования возможность динамического создания.
Помните, что деструктор выполняется при удалении указателя на динамически созданный объект (см. раздел 13.1.3). Если это указатель на тип в иерархии наследования, вполне возможно, что статический тип указателя может отличаться от динамического типа удаляемого объекта (см. раздел 15.2.2). Например, при удалении указателя типа Quote*
может оказаться, что он указывал на объект класса Bulk_quote
. Если он указывает на объект типа Bulk_quote
, компилятор должен знать, что следует выполнить деструктор именно класса Bulk_quote
. Подобно любой другой функции, чтобы был выполнен надлежащий деструктор, в базовом классе его следует определить как виртуальную функцию:
class Quote {
public:
// виртуальный деструктор необходим при удалении указателя на
// базовый тип, указывающего на объект производного
virtual ~Quote() = default; // динамическое связывание для
// деструктора
};
Подобно любой другой виртуальной функции, виртуальный характер деструктора наследуется. Таким образом, у классов, производных от класса Quote, окажутся виртуальные деструкторы, будь то синтезируемый деструктор или собственный. Пока деструктор базового класса остается виртуальной функцией, при удалении указателя на базовый класс будет выполнен соответствующий деструктор:
Quote *itemP = new Quote; // статический и динамический типы совпадают
delete itemP; // вызов деструктора для Quote
itemP = new Bulk_quote; // статический и динамический типы разные
delete itemP; // вызов деструктора для Bulk_quote
Выполнение оператора
delete
для указателя на базовый класс, который указывает на объект производного класса, приведет к непредсказуемым последствиям, если деструктор базового класса не будет виртуальным.
Деструкторы базовых классов — важное исключение из эмпирических правил, согласно которым, если класс нуждается в деструкторе, то он также нуждается в функциях копирования и присвоения (см. раздел 13.6). Базовый класс почти всегда нуждается в деструкторе, поэтому он может сделать деструктор виртуальным. Если базовый класс обладает пустым деструктором, только чтобы сделать его виртуальным, то наличие у класса деструктора вовсе не означает, что также необходим оператор присвоения или конструктор копий.
Тот факт, что базовый класс нуждается в виртуальном деструкторе, имеет важное косвенное последствие для определения базовых и производных классов: если класс определит деструктор (даже с использованием синтаксиса = default
, чтобы использовать синтезируемую версию), то компилятор не будет синтезировать функцию перемещения для этого класса (см. раздел 13.6.2).
Упражнение 15.24. Какие виды классов нуждаются в виртуальном деструкторе? Какие задачи должен выполнять виртуальный деструктор?
15.7.2. Синтезируемые функции управления копированием и наследование
Синтезируемые функции-члены управления копированием в базовом или производном классе выполняются, как любой другой синтезируемый конструктор, оператор присвоения или деструктор: они почленно инициализируют, присваивают или удаляют члены самого класса. Кроме того, эти синтезируемые члены инициализируют, присваивают или удаляют прямую базовую часть объекта при помощи соответствующей функции базового класса. Соответствующие примеры приведены ниже.
• Синтезируемый стандартный конструктор класса Bulk_quote
запускает стандартный конструктор класса Disc_quote
, который в свою очередь запускает стандартный конструктор класса Quote
.
• Стандартный конструктор класса Quote
инициализирует по умолчанию переменную-член bookNo
пустой строкой и использует внутриклассовый инициализатор для инициализации переменной-члена price
нулем.
• Когда конструктор класса Quote
завершает работу, конструктор класса Disc_quote
продолжает ее, используя внутриклассовые инициализаторы для инициализации переменных qty
и discount
.
• Когда завершает работу конструктор класса Disc_quote
, конструктор класса Bulk_quote
продолжает ее, но не выполняет никаких других действий.
Точно так же синтезируемый конструктор копий класса Bulk_quote
использует (синтезируемый) конструктор копий класса Disc_quote
, который использует (синтезируемый) конструктор копий класса Quote
. Конструктор копий класса Quote
копирует переменные-члены bookNo
и price
; а конструктор копий класса Disc_quote
копирует переменные-члены qty
и discount
.
Следует заметить, что не имеет значения, синтезируется ли функция-член базового класса (как в случае иерархии Quote
) или имеет предоставленное пользователем определение. Важно лишь то, что соответствующая функция-член доступна (см. раздел 15.5) и что она не удаленная.
Каждый из классов иерархии Quote
использует синтезируемый деструктор. Производные классы делают это неявно, тогда как класс Quote
делает это явно, определяя свой (виртуальный) деструктор как = default
. Синтезируемый деструктор (как обычно) пуст, и его неявная часть удаляет члены класса (см. раздел 13.1.3). В дополнение к удалению собственных членов фаза удаления деструктора в производном классе удаляет также свою прямую базовую часть. Этот деструктор в свою очередь вызывает деструктор своего прямого базового класса, если он есть. И так далее до корневого класса иерархии.
Как уже упоминалось, у класса Quote
нет синтезируемых функций перемещения, поскольку он определяет деструктор. При каждом перемещении объекта Quote
(см. раздел 13.6.2) будут использоваться (синтезируемые) функции копирования. Как будет продемонстрировано ниже, тот факт, что у класса Quote
нет функций перемещения, означает, что его производные классы также не будут их иметь.
Интервал:
Закладка: