Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
При создании, копировании, перемещении и присвоении объектов производного класса сначала создается, копируется, перемещается и присваивается базовая часть объекта. Деструкторы выполняются в обратном порядке: сначала удаляется производная часть, затем выполняются деструкторы частей базовых классов. Базовые классы обычно определяют виртуальный деструктор, даже если у них нет никакой потребности в деструкторе.
Производный класс определяет уровень защиты для каждого из своих базовых классов. Члены открытого базового класса являются частью интерфейса производного класса; члены закрытого базового класса недоступны; члены защищенного базового класса доступны для классов, производных от него, но не для пользователей производного класса.
Термины
Абстрактный класс (abstract base class). Класс, обладающий одной или несколькими чистыми виртуальными функциями. Нельзя создать объекты типа абстрактного базового класса.
Базовый класс (base class). Класс, от которого происходит другой класс. Члены базового класса становятся членами производного класса.
Виртуальная функция (virtual function). Функция-член, обеспечивающая зависимое от типа поведение. Во время выполнения выбор конкретной версии функции при обращении к виртуальной функции с помощью ссылки или указателя осуществляется на основании типа объекта, с которым связана ссылка или указатель.
Динамический тип (dynamic type). Тип объекта во время выполнения. Динамический тип объекта, на который ссылается ссылка или указывает указатель, может отличаться от статического типа ссылки или указателя. Указатель или ссылка на тип базового класса может применяться к объекту производного типа. В таких случаях статическим типом будет ссылка (или указатель) на базовый класс, а динамическим — ссылка (или указатель) на производный.
Динамическое связывание (dynamic binding). Отсрочка выбора выполняемой функции до времени выполнения. В языке С++ динамическим связыванием называют выбор во время выполнения используемой версии виртуальной функции на основании фактического типа объекта, который связан со ссылкой или с указателем.
Доступность (accessible). Член базового класса доступен через производный объект. Доступность зависит от спецификатора доступа, используемого в списке наследования производного класса, и уровня доступа члена в базовом классе. Например, открытый (public) член класса, унаследованный при открытом наследовании, доступен для пользователей производного класса. Открытый член базового класса недоступен, если наследование является закрытым.
Закрытое наследование (private inheritance). При закрытом наследовании открытые и защищенные члены базового класса становятся закрытыми членами производного.
Защищенное наследование (protected inheritance). При защищенном наследовании защищенные и открытые члены базового класса становятся защищенными членами производного.
Косвенный базовый класс (indirect base class). Базовый класс, отсутствующий в списке наследования производного класса. Класс, от которого наследуется прямой базовый класс, прямо или косвенно является косвенным базовым классом для производного класса.
Наследование (inheritance). Программная технология определения нового класса (производного) в терминах существующего класса (базового). Производный класс наследует члены базового класса.
Объектно-ориентированное программирование (object-oriented programming). Техника программирования с использованием абстракции данных, наследования и динамического связывания.
Открытое наследование (public inheritance). Открытый интерфейс базового класса является частью открытого интерфейса производного класса.
Отсечение (sliced down). Происходящее при использовании объекта производного типа для инициализации или присвоения объекта базового типа. Производная часть объекта отсекается, оставляя только базовую часть, которая и присваивается объекту базового типа.
Переопределение (override). Виртуальная функция, определенная в производном классе, с тем же списком параметров, что и у виртуальной функции в базовом классе, переопределяет определение базового класса.
Полиморфизм (polymorphism). Применительно к объектно-ориентированному программированию — возможность получить специфическое для типа поведение на основании динамического типа ссылки или указателя.
Преобразование производного класса в базовый (derived-to-base conversion). Неявное преобразование объекта производного класса в ссылку на базовый класс или указателя на объект производного класса в указатель на базовый класс.
Привязка во время выполнения (run-time binding). См. динамическое связывание.
Производный класс (derived class). Класс, унаследованный от другого класса. Производный класс может переопределить виртуальные функции своего базового класса и определять новые члены. Область видимости производного класса вкладывается в область ее базового класса (классов); члены производного класса могут использовать члены базового класса непосредственно.
Прямой базовый класс (direct base class). Базовый класс, от которого непосредственно происходит производный. Прямые базовые классы определяются в списке наследования производного класса. Прямой базовый класс сам может быть производным классом.
Рефакторинг (refactoring). Способ перепроектирования программ, позволяющий собрать взаимосвязанные части в единую абстракцию при замене первоначального кода новой абстракцией. Рефакторинг классов, как правило, применяют для перемещения переменных или функций-членов в самый верхний общий пункт иерархии во избежание дублирования кода.
Спецификатор доступа protected. К членам, определенным после ключевого слова protected, могут обращаться только члены производного класса и друзья. Однако доступны эти члены только через производные объекты. Защищенные члены не доступны для обычных пользователей класса.
Список наследования класса (class derivation list). Список базовых классов, от которых происходит производный класс; у каждого из них может быть необязательный уровень доступа. Если спецификатора доступа нет, наследование открытое (public), если производный класс определен с ключевым словом struct, и закрытое (private), если класс определен с ключевым словом class.
Статический тип (static type). Тип, с которым определяется переменная или возвращает выражение. Статический тип известен во время компиляции.
Чистая виртуальная функция (pure virtual). Виртуальная функция, объявленная в заголовке класса с использованием = 0 в конце списка параметров функции. Чистая виртуальная функция не обязана (но вполне может) быть определена классом. Класс с чистой виртуальной функцией является абстрактным. Если производный класс не определяет собственную версию унаследованной чистой виртуальной функции, он также становится абстрактным.
Глава 16
Шаблоны и обобщенное программирование
И объектно-ориентированное, и обобщенное программирование имеют дело с типами, неизвестными на момент написания программы. Различие между ними в том, что объектно-ориентированное программирование имеет дело с типами, которые не известны до времени выполнения, тогда как в обобщенном программировании типы становятся известны только во время компиляции.
Все описанные в части II контейнеры, итераторы и алгоритмы являются хорошими примерами обобщенного программирования. При написании обобщенной программы ее код должен работать способом, независимым от специфических типов. При использовании обобщенного кода ему следует предоставить типы или значения, с которыми будет работать данный конкретный экземпляр кода.
Например, библиотека предоставляет единое, обобщенное определение каждого контейнера, такого как вектор. Это обобщенное определение можно использовать для определения множества разных типов векторов, каждый из которых отличается от других типом хранимых элементов.
Шаблоны (template) — это основа обобщенного программирования. Шаблоны вполне можно использовать (как выше в книге), даже не понимая, как они определяются. В этой главе рассматривается определение собственных шаблонов.
В языке С++ шаблоны являются основой для общего программирования. Шаблон — это проект или формула для создания класса или функции.
При использовании такого обобщенного типа, как vector, или такой обобщенной функции, как find(), следует предоставить дополнительную информацию, необходимую для трансформации их проекта в конкретный класс или функцию во время компиляции. Использование шаблонов рассматривалось в главе 3, а в этой главе мы изучим их определение.