
- •6Vpj7-h3cxh-hbtpt-x4t74-3yvy7
- •Оглавление
- •Предисловие
- •Введение
- •1.1. Понятие класса и объекта. Инкапсуляция
- •1.2. Определение классов. Компоненты. Доступность
- •Class_key /*class_id*/ { /*members_list*/ };
- •Value_type class_id::function_id(parameters) {statements}
- •CPoint point1(100,70); // локальный объект
- •Static cPoint point3(50,120); // статический объект
- •Class_id(parameters) /*:initializer_list*/ {/*statements*/}
- •CString(const char *);
- •Delete[] __thematrix;
- •1.4. Обращение к компонентам объектов
- •1.5. Статические и нестатические компоненты классов
- •1.7. Указатель this
- •В опросы для самопроверки
- •2. Механизм наследования. Полиморфизм
- •2.1. Формы наследования. Базовые и производные классы
- •Class_key class_id: inheritance_specifier base_class_id {member_list};
- •2.3. Абстрактные классы
- •2.4. Множественное наследование и виртуальные классы
- •2.5. Преобразование динамических типов. Динамическая идентификация типов
- •Catch ( std::bad_cast & ) { // обработка исключения
- •Return 0;
- •Вопросы для самопроверки
- •3. Дружественные функции и классы
- •3.1. Дружественные функции
- •3.2. Дружественные классы
- •Вопросы для самопроверки
- •4. Механизм вложения
- •4.1. Вложенные классы
- •4.2. Локальные классы
- •Вопросы для самопроверки
- •5. Объектная модель и шаблоны
- •5.1. Определение, описание и инстанцирование шаблонов
- •::Function_id(function_parameter_list) { statements }
- •5.2. Параметры и аргументы шаблонов
- •Class identifier typename identifier
- •// Key, Data – параметры-типы (типы ключа и данных отображения)
- •// Container – контейнер, где содержится информация отображения class сMap {
- •Class MyTemplate
- •Int array[10]; struct Structure { int m; static int sm; } str;
- •5.3. Шаблоны компонентных функций
- •Value_type function_template_id(function_parameter_list) { statements }
- •::Function_template_id(function_parameter_list) { statements }
- •5.4. Специализация шаблонов
- •Вопросы для самопроверки
- •6. Перегрузка операций
- •Value_type operator @ (parameter_list);
- •Value_type operator @ (parameter_list) { statements }
- •Return fail();
- •6.3. Перегрузка бинарных операций
- •Value_type operator @ (parameter); // компонентная функция
- •Value_type operator @ (parameter, parameter); // глобальная функция friend value_type operator @ (parameter, parameter); // дружественная функция
- •Return *this;
- •Return *this;
- •/* Присваиваем собственные данные класса d */
- •6.4. Перегрузка операций управления памятью
- •Typedef void (*new_handler) ();
- •Extern new_handler set_new_handler( new_handler new_p );
- •Void operator delete(void * memory) {
- •... // Специальная обработка пользователя ::operator delete(memory); // освободить память
- •Вопросы для самопроверки
- •7. Механизм исключений
- •Throw expression
- •7.3. Специальные средства поддержки механизма исключений
- •Unexpected_function set_unexpected(unexpected_function func_name);
- •Typedef void (* unexpected_function) ();
- •Extern char * __throwExceptionName; extern char * __throwFileName; extern unsigned __throwLineNumber;
- •Вопросы для самопроверки
- •8. Подсчет ссылок
- •8.1. Назначение механизма подсчета ссылок
- •8.2. Контекстно-независимая модель счетчика ссылок
- •8.4. Внедрение подсчета ссылок в существующий класс
- •Вопросы для самопроверки
- •9. Стандартная библиотека шаблонов (stl)
- •9.1. Назначение и архитектура stl
- •9.2. Последовательные контейнеры
- •Class vector {
- •// Определение итераторов
- •Sort(first,last); // сортировка вектора в диапазоне итераторов
- •Ifstream ifile ("example.In"); ofstream ofile ("example.Out");
- •OutputIterator copy(
- •InputIterator first, InputIterator last, OutputIterator result );
- •// Заполнение списка
- •Operator- (int)
- •Operator- (random access iterator) operator[] (int)
- •InputIterator find(InputIterator first, InputIterator last, const t & value);
- •InputIterator find(InputIterator first, InputIterator last, const t & value)
- •Return first;
- •OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
- •Return result;
- •OutputIterator transform (InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op)
- •Return result;
- •Void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp)
- •__Quick_sort_loop(first, last, comp); __final_insertion_sort(first, last, comp);
- •T accumulate(InputIterator first, InputIterator last, t init, Function f);
- •V.Push_back(2); V.Push_back(5);
- •9.5. Функторы
- •T operator()(const t & X) const { return -X; }
- •9.7. Адаптеры
- •S1.Push(1); s1.Push(5);
- •// Записать в вектор числа 1 2 3 4
- •// Сортировать по неубыванию
- •// Записать в вектор числа 4 6 10 3 13 2
- •Вопросы для самопроверки
- •Заключение
- •Библиографический Список
- •6Vpj7-h3cxh-hbtpt-x4t74-3yvy7
Return 0;
}
Работа приведенной программы очевидна из комментариев. Единственное, о чем следует сказать отдельно, – обработка модификаторов const, volatile, const volatile. Операция typeid, согласно стандарту, игнорирует любые модификаторы первого уровня. Например, const A и A, const B & и B она будет считать идентичными типами соответственно, а const A * и A * она будет различать (здесь const – модификатор второго уровня).
Рассмотренный в данной главе механизм наследования существенно расширяет возможности языка С++ с точки зрения формирования новых классов и отношений между ними. В то же время, существуют ситуации, когда наследование не дает достаточно гибких решений или вообще неприменимо ввиду концептуальных ограничений предметной области. В этих случаях более разумным может оказаться использование механизма дружественных функций и классов, который рассмотрен в следующей главе, а также механизма вложения, описанного в главе 4.
Вопросы для самопроверки
Охарактеризуйте понятие наследования.
Какие формы наследования поддерживаются в С++?
Дайте общий формат определения производного класса.
Опишите структуру объекта производного класса.
В каком порядке вызываются конструкторы и деструкторы при создании и удалении объекта производного класса?
В каких случаях при построении производного класса целесообразно использование закрытого и защищенного наследования? Дайте обоснование и приведите пример.
Дан класс CEmployee, описывающий сотрудника некоторой фирмы, а также классы CChief и COrdinary, представляющие соответственно руководящих и рядовых сотрудников этой фирмы. Как наиболее эффективно объединить эти классы в иерархию? Приведите эскиз.
Дан класс CDate, описывающий даты, и класс CEmployee, представляющий сотрудников некоторой организации. Класс CEmployee должен содержать дату рождения сотрудника; для ее представления разумно использовать уже готовый класс CDate. Какую схему наследования необходимо применить, чтобы эффективно использовать функциональность класса CDate в классе CEmployee. Привести эскиз классовой иерархии и дать ее обоснование.
Дан класс CPerson, описывающий человека, и класс CEmployee, представляющий сотрудников некоторой организации. Ясно, что класс CEmployee будет содержать многое из того, что есть в CPerson, поэтому разумно связать эти два класса отношением наследования. Какую схему наследования необходимо применить, чтобы эффективно использовать функциональность класса CPerson в классе CEmployee. Привести эскиз классовой иерархии и дать ее обоснование.
Даны классы CArmor, CFighter, CBomber, CArtillery, представляющие вражеские цели в программе «виртуальная карта разведчика» (CArmor – танки, CFighter – истребители, CBomber – бомбардировщики, CArtillery – артиллерийские орудия). Как наиболее рационально связать эти классы в иерархию?
Что такое полиморфизм?
В чем отличие между статическим и виртуальным полиморфизмом? Приведите пример.
Какие классы принято называть полиморфными?
Приведите концептуальные отличия между виртуальными и невиртуальными компонентными функциями.
Почему деструктор базового класса обязательно должен быть виртуальным? Опишите возможные последствия его «невиртуальности» на примере.
В каком случае приведенное ниже определение деструктора базового класса X следует считать правильным и безопасным: ~X() { delete[] __data; } ? Поясните ответ.
Пусть в некотором классе CSomeClass есть компонентная функция SomeFunc. Класс CSomeClass предполагается использовать в качестве базового в классовой иерархии. По каким признакам можно определить, следует ли делать функцию SomeFunc виртуальной?
Класс CMatrix содержит функцию virtual void Input(); Производный от него класс CSpecialMatrix включает функцию virtual void Input(istream &); К чему приводит несоответствие сигнатур функции Input в базовом и производном классах?
Требуется спроектировать классы, представляющие прямоугольники, квадраты, эллипсы, окружности и треугольники. Как наиболее рационально построить иерархию из этих классов? Приведите эскизы определения классов.
Какие классы называют абстрактными? Приведите пример определения абстрактного класса.
Как поступить, если проектируемый класс надо сделать абстрактным, но функций, которые можно было бы объявить чисто виртуальными, нет?
При каком условии возможно создание объекта абстрактного класса?
Опишите концептуальные отличия между виртуальными и чисто виртуальными функциями.
Имеется класс, описывающий интерфейсные окна графической системы. Выделите те аспекты поведения этого класса, которые позволяют сделать его абстрактным.
Что понимается под статическим и динамическим типами выражения?
Как можно получить название текущего динамического типа выражения? Приведите фрагмент кода.
Каким образом можно сравнить динамические типы двух выражений?
Класс C определен в виде: class C: A, B { /* */ }; Определения классов A, B, в свою очередь, имеют вид: class A: W { /* */ }; class B: W { /* */ }; (здесь W – еще один класс). Правильно ли определен конструктор класса C, если известно, что во всех классах A, B, C, W определены конструкторы по умолчанию: C::C(): A(), B() {} Будет ли это определение верным при виртуальном базовом классе W?
Опишите сущность проблемы доминирования виртуальных функций при множественном наследовании.
Каковы особенности применения операции dynamic_cast в иерархиях классов с множественным наследованием?
Можно ли один и тот же базовый класс использовать и как виртуальный, и как невиртуальный? Приведите пример такой иерархии классов.
Каким образом можно сделать функцию виртуальной по отношению к двум динамическим типам одновременно? Ответ поясните примером.
Задачи
Разработать иерархию классов для представления возможностей виртуальных радиоприемников и магнитофонов. При разработке максимально использовать возможности наследования, чтобы сократить объем дублируемого кода. Показать использование объектов-приемников и -магнитофонов.
Построить иерархию классов, моделирующую вражеские цели в вооруженном конфликте: "танки", "бомбардировщики" и "истребители". При разработке максимально использовать возможности наследования, чтобы сократить объем дублируемого кода. Показать использование объектов-целей в программе.
Придумать иерархию классов, которая бы наиболее рационально представляла животных в виртуальном справочнике любителя животных. Необходимо представить только классы млекопитающих, птиц и рыб. Для моделирования общих свойств этих классов можно использовать абстрактные базовые классы.
Предложить иерархию классов, описывающую цели для пункта управления огнем дивизионной артиллерии. Требуется представить следующие классы целей: бронированные машины (БТР, танки); стационарные артиллерийские орудия (гаубицы, системы залпового огня); пункты сосредоточения личного состава (штабы, казармы). Для описания общих свойств классов можно применить абстрактные базовые классы.
Разработать фрагмент иерархии классов для компьютерной игры "Подземелье гоблинов". Суть игры проста: в подземном лабиринте, где есть клад, живут гоблины. Задача героя - найти клад. Но гоблины не только помогают герою в поисках клада, но и мешают. Разработке подлежат классы: гоблин; злой гоблин (мешает герою в поисках клада); добрый гоблин (помогает герою найти клад); гоблин-хамелеон (это гоблин, который может быть как злым, так и добрым в зависимости от обстоятельств).
Разработать часть классовой иерархии для описания объектов системы автоматического управления. В число классов включаются: объект управления, робот, технологическая ячейка, роботизированная технологическая ячейка.