1. А. Пол
ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ НА C++
Книга Айры Пола, автора многих популярных изданий по С и C++, не является
ни учебником по C++, ни курсом по объектно-ориентированному
программированию (ООП) «вообще», хотя может быть полезна и в этих двух
качествах. Задача книги (точно отраженная в названии) совершенно конкретна:
научить читателя писать на C++ объектно-ориентированные программы. Для
многих абстрактных идей и понятий ООП в C++ существуют конкретные
воплощающие их конструкции. В каждой главе автор вводит и объясняет
очередную «порцию» таких конструкций, демонстрирует технику их
эффективного использования. В некоторых случаях возникающие перед
программистом на C++ проблемы не могут быть непосредственно решены
средствами языка. Здесь на помощь приходят разнообразные приемы, не владея
которыми трудно программировать на C++ реальные задачи. Такие приемы
поясняются автором на многочисленных примерах, причем наиболее
показательные программы подвергаются тщательному разбору.
Много внимания на страницах книги уделено самым последним дополнениям
C++: стандартной библиотеке шаблонов (STL), пространствам имен (namespaces),
механизму идентификации типов во время выполнения (RTTI), явным
приведениям типов (cast-операторам) и другим.
Книга в первую очередь рассчитана на программистов, желающих получить
ясное представление о парадигме объектно-ориентированного программирования
в C++. Издание также будет полезно преподавателям, студентам и всем, кто хочет
освоить объектно-ориентированное программирование на C++.
Содержание
Предисловие 13
Глава 1
Зачем нужно объектно-ориентированное программирование на C++? 17
1.1. Объектно-ориентированное программирование 18
1.2. Пример программы на C++ 19
1.3. Инкапсуляция и расширяемость типов 21
1.4. Конструкторы и деструкторы 23
1.5. Перегрузка 25
1.6. Шаблоны и обобщенное программирование 27
1.7. Стандартная библиотека шаблонов (STL) 29
1.8. Наследование 30
1.9. Полиморфизм 32
1.10. Исключения в C++ 34
1.11. Преимущества объектно-ориентированного программирования 35
Глава 2
Собственные типы данных и инструкции 37
2.1. Элементы программы 37
2.1.1. Комментарии 38
2.1.2. Ключевые слова 38
2. 2.1.3. Идентификаторы 39
2.1.4. Литералы 39
2.1.5. Операторы и знаки пунктуации 41
2.2. Ввод-вывод 41
2.3. Структура программы 42
2.4. Простые типы 44
2.4.1. Инициализация 45
2.5. Традиционные преобразования 46
2.6. Перечислимые типы 49
2.7. Выражения 50
2.8. Инструкции 53
2.8.1. Присваивание и выражения 53
2.8.2. Составная инструкция 55
2.8.3. Инструкции if и if-else 55
2.8.4. Инструкция while 56
2.8.5. Инструкция for 56
2.8.6. Инструкция do 57
2.8.7. Инструкции break и continue 58
2.8.8. Инструкция switch 59
2.8.9. Инструкция goto 60
2.9. Практические замечания 61
Резюме 61
Упражнения 63
Глава 3
Функции и указатели 69
3.1. Функции 69
3.1.1. Вызов функции 69
3.2. Определение функции 70
3.3. Инструкция return 71
3.4. Прототипы функций 72
3.5. Аргументы по умолчанию 74
3.6. Перегрузка функций 75
3.7. Встраивание 76
3.8. Область видимости и класс памяти 77
3.8.1. Класс памяти auto 78
3.8.2. Класс памяти register 79
3.8.3. Класс памяти extern 79
3.8.4. Класс памяти static 81
3.8.5. Таинства компоновки 82
3.9. Пространства имен 82
3.10. Типы указателей 83
3.10.1. Определение адреса и разыменование 84
3.10.2. Вызов по ссылке на основе указателей 84
3.11. Применение void 86
3. 3.12. Массивы и указатели 86
3.12.1. Индексирование 87
3.12.2. Инициализация 88
3.13. Связь между массивами и указателями 88
3.14. Передача массивов функциям 89
3.15. Объявления ссылок и вызов по ссылке 90
3.16. Проверка утверждений и корректность программы 92
3.17. Строки: соглашение о char* 94
3.18. Многомерные массивы 95
3.19. Операторы свободной памяти new и delete 95
3.20. Практические замечания 98
3.20.1. void* и reinterpret_cast 98
3.20.2. Замена объявлений static extern 98
Резюме 99
Упражнения 100
Глава 4
Реализация АТД в базовом языке 107
4.1. Агрегатный тип struct 107
4.2. Оператор указателя структуры 109
4.3. Пример: стек 109
4.4. Объединения 113
4.5. Комплексные числа 115
4.6. Пример: флеш 116
4.7. Битовые поля 120
4.8. Пример: двумерные динамические массивы 121
4.9. Практические замечания 124
Резюме 124
Упражнения 125
Глава 5
Сокрытие данных и функции-члены класса 131
5.1. Функции-члены класса 132
5.2. Доступ: закрытый и открытый 135
5.3. Классы 136
5.4. Область видимости класса 138
5.4.1. Оператор разрешения области видимости :: 138
5.4.2. Вложенные классы 139
5.5. Пример: пересмотрим флеш 140
5.6. Статические члены данных 142
5.7. Указатель this 143
5.8. Функции-члены типа static и const 144
5.8.1. Изменчивость (mutable) 146
5.9. Контейнеры и доступ к их содержимому 147
5.10. Практические замечания 149
Резюме 150
4. Упражнения 151
Глава 6
Создание и уничтожение объектов 155
6.1. Классы с конструкторами 156
6.1.1. Конструктор по умолчанию 157
6.1.2. Инициализатор конструктора 157
6.1.3. Конструкторы как преобразования 158
6.2. Создание динамического стека 159
6.2.1. Копирующий конструктор 160
6.3. Классы с деструкторами 161
6.4. Пример: динамически размещаемые строки 162
6.5. Класс vect 166
6.6. Члены данных, являющиеся классами 168
6.7. Пример: односвязный список 169
6.8. Двумерные массивы 173
6.9. Многочлен как связный список 174
6.10. Строки, использующие семантику ссылок 179
6.11. В отсутствии конструктора, копирующий конструктор и другие
тайны
181
6.11.1. Деструкторы: некоторые детали 182
6.12. Практические замечания 182
Резюме 183
Упражнения 184
Глава 7
Ad hoc полиморфизм 191
7.1. Преобразования АТД 192
7.2. Перегрузка и выбор функций 193
7.3. Дружественные функции 195
7.4. Перегрузка операторов 197
7.5. Перегрузка унарных операторов 199
7.6. Перегрузка бинарных операторов 201
7.7. Перегрузка операторов присваивания и индексирования 202
7.8. Многочлены: что можно ждать от типа и языка 206
7.9. Перегруженные операторы ввода-вывода « и » 207
7.10. Перегрузка оператора () для индексирования 208
7.11. Операторы указателей 210
7.11.1. Указатель на член класса 212
7.12. Перегрузка new и delete 214
7.13. Практические замечания 216
7.13.1. Соответствие сигнатуре 217
Резюме 218
Упражнения 220
Глава 8
Перебор: итераторы и контейнеры 227
5. 8.1. Перебор 227
8.2. Итераторы 228
8.3. Пример:quicksort() 229
8.4. Дружественные классы и итераторы 232
8.5. Обобщенное программирование с использованием void* 234
8.6. Список и итератор списка 236
8.7. Практические замечания 239
Резюме 240
Упражнения 241
Глава 9
Шаблоны, обобщенное программирование и STL 245
9.1. Шаблонный класс stack 245
9.2. Шаблоны функций 247
9.2.1. Соответствие сигнатуре и перегрузка 249
9.3. Шаблоны классов 250
9.3.1. Друзья 250
9.3.2. Статические члейы 250
9.3.3. Аргументы шаблона класса ——
250
9.4. Параметризация класса vector 251
9.5. Параметризация quicksort^) 254
9.6. Параметризованное дерево двоичного поиска 255
9.7. STL 259
9.8. Контейнеры 260
9.8.1. Последовательные контейнеры 262
9.8.2. Ассоциативные контейнеры 263
9.8.3. Адаптеры контейнеров 265
9.9. Итераторы 267
9.9.1. Итераторы istream_iterator и ostream_iterator 268
9.9.2. Адаптеры итераторов 269
9.10. Алгоритмы 269
9.10.1. Алгоритмы сортировки 270
9.10.2. Не изменяющие последовательность алгоритмы 270
9.10.3. Изменяющие последовательность алгоритмы 271
9.10.4. Численные алгоритмы 272
9.11. Функции 273
9.12. Адаптеры функций 275
9.13. Практические замечания 276
Резюме 276
Упражнения 277
Глава 10
Наследование 281
10.1. Производный класс 282
10.2. Преобразования типов и видимость 284
6. 10.3. Повторное использование кода: класс двоичного дерева 286
10.4. Виртуальные функции 289
10.5. Абстрактные базовые классы 293
10.6. Шаблоны и наследование 297
10.7. Множественное наследование 299
10.8. Наследование и проектирование 301
10.8.1. Форма подтипов 302
10.9. Идентификация типа на этапе выполнения 304
10.10. Практические замечания 305
Резюме 306
Упражнения 307
Глава 11
Исключения 311
11.1. Использование assert.h 311
11.2. Использование signal.h 312
11.3. Исключения C++ 316
11.4. Запуск исключений 317
11.4.1. Перезапуск исключений 318
11.4.2. Выражения исключений 319
11.5. Пробные блоки try 319
11.6. Обработчики 320
11.7. Спецификация исключения 321
11.8. terminate() и unexpected() 321
11.9. Пример кода с исключениями 322
11.10. Стандартные исключения и их использование 324
11.11. Практические замечания 325
Резюме 326
Упражнения 328
Глава 12
ООП на C++ 331
12.1. Требования к языку ООП 331
12.2. АТД в не-ООП языках 332
12.3. Клиенты и производители 333
12.4. Повторное использование кода и наследование 334
12.5. Полиморфизм 335
12.6. Сложность языка 336
12.7. Успех ООП на C++ 337
12.8. Платонизм: проектирование «tabula rasa» 338
12.9. Принципы проектирования 340
12.10. Схемы, диаграммы и инструменты 341
12.11. Штампы проектирования 343
12.12. C++: критика 343
Резюме 345
Упражнения 346
7. Приложение А
Коды символов ASCII 349
Приложение В
Приоритет и порядок выполнения операторов 351
Приложение С
Руководство по языку 353
С.1. Структура программы 353
С.2. Лексические элементы 353
С.2.1. Комментарии 354
С.2.2. Идентификаторы 354
С.2.3. Ключевые слова 355
С.3. Константы 355
С.4. Объявления и правила области видимости 357
С.5. Пространства имен 359
С.6. Правила компоновки 360
С.7. Типы 362
С.8. Приведения и правила преобразований 364
С.9. Выражения и операторы 367
С.9.1. Выражения sizepf 367
С.9.2. Выражения автоинкремента и автодекремента 368
С.9.3. Арифметические выражения 368
С.9.4. Выражения отношения, равенства и логические выражения 368
С.9.5. Выражения присваивания 369
С.9.6. Выражения с запятой 370
С.9.7. Условные выражения 370
С.9.8. Выражения с битовыми операторами 371
С.9.9. Выражения с определением адреса и обращением по адресу 371
С.9.10. Выражения с new и delete 372
С.9.11. Другие выражения 374
С.10. Инструкции 375
С.10.1. Инструкции-выражения 376
С.10.2. Составная инструкция 376
С.10.3. Инструкции if и if-else 377
С.10.4. Инструкция while 377
С.10.5. Инструкция for 377
С.10.6. Инструкция do 378
С.10.7. Инструкции break и continue 379
С.10.8. Инструкция switch 379
С.10.9. Инструкция goto 380
С.10.10. Инструкция return 381
С.10.11. Инструкция-объявление 381
С.11. Функции 381
С.11.1. Прототипы 382
С.11.2. Вызов по ссылке 383
8. С.11.3. Встроенные функции 383
С.11.4. Аргументы по умолчанию 383
С.11.5. Перегрузка 383
С.11.6. Типобезопасная компоновка для функций 385
С.12. Классы 385
С.12.1. Конструкторы и деструкторы 386
С.12.2. Функции-члены 387
С.12.3. Дружественные функции 387
С.12.4. Указатель this 388
С. 12.5. Перегрузка операторов 388
С.12.6. Функции-члены типа static и const 390
С.12.7. Изменчивость (mutable) 391
С.12.8. Проектирование классов 391
С.13. Наследование 391
С.13.1. Множественное наследование 393
С.13.2. Вызов конструктора 394
С.13.3. Абстрактные базовые классы 394
С.13.4. Указатель на член класса 394
С.13.5. Идентификация типа на этапе выполнения 394
С.13.6. Виртуальные функции 395
С.14. Шаблоны 396
С.14.1. Параметры шаблона 397
С.14.2. Шаблоны функций 398
С.14.3. Друзья 399
С.14.4. Статические члены 399
С.14.5. Специализация 400
С. 15. Исключения 400
С.15.1. Запуск исключений 401
С.15.2. Пробные блоки try 402
С.15.3. Обработчики 403
С.15.4. Спецификация исключения 403
С.15.5. terminate() и unexpected() 404
С.15.6. Стандартные библиотечные исключения 404
С.16. Предосторожности, связанные с совместимостью 404
С.16.1. Объявления вложенных классов 405
С.16.2. Совместимость типов 405
С.16.3. Разное 405
С.17. Новые возможности C++ 406
Приложение D
Ввод-вывод 407
D.1. Класс вывода ostream 407
D.2. Форматированный вывод и iomanip.h 408
D.3. Пользовательские типы: вывод 410
D.4. Класс ввода istream 412
23. vect_it.h 251
vect_ovl.cpp 389
vect1.h 166
vect2.h 203
vect3.h 315, 385
vect4.cpp 322
vect4.h 316, 322
vectacum.cpp 229
vector.h 228, 229
vectsort.cpp 230
virt_err.cpp 291
virt_sel.cpp 290
weekend.cpp 113
while_t.cpp 56
word_cnt.cpp 418
проектирование 301, 340
штамп 343
производитель
АТД 131
класса 333
производный класс 281, 282, 283
простой тип 37, 44
пространство имен 20, 41, 82, 359,
360
namespace std 360
безымянное 81, 83, 98
прототип функции 72, 382
список объявлений аргументов
73
псевдоним 90
пунктуация 41
Р
разбросанный многочлен 174
размещение 214, 374
разрешение области видимости 133,
138
разыменование указателя 86, 371
раскрытие макро 76
распределитель памяти 437
расширение типа 47
расширяемость типов 21, 37
регистровый класс памяти 79
С
сборка мусора 179, 344
свободная память 95, 372
связывающий адаптер 275, 437
сигнал 313
сигнатура функции 32, 76, 384
символ конца строки, 0 24
символьная константа 40, 356
символьный литерал 40
сложение многочленов 175
методом сортировки со
слиянием 177
смесь 302
смешанное выражение 46
совместимость
с языком С 404
типов 405
сокрытие
данных 132, 136
имени переменной 77
сообщение 21, 291
сортировка, быстрая 229
составная инструкция 55, 376
состояние потока 417
сотрудничество 341
специализация шаблона 400
спецификация исключения 321, 403
списки 30, 47, 282, 320, 335, 364, 402
STL: адаптеры итераторов 427
адаптеры функций 275, 437
алгоритм выбора
перегруженной функции 193,
250, 384, 399
виды объектов-функций 274,
435
вызов по ссылке с
использованием указателей 85
интерфейсы типичных
контейнеров STL 260, 421
использование копирующего
конструктора 164, 386
использование функций в C++
305
как работает инструкция switch
60, 380
категории библиотеки
24. алгоритмов STL 269, 428
концепции ООП 19
некоторые функции из
библиотеки cstring 94
операции над списком 169
организация программы на C++
43, 353
порядок выполнения
конструкторов 301, 394
преимущества использования
производных классов 283
различия в типах по сравнению
с ANSI С 405
типы полиморфизма 335
характеристики языка ООП 331
черный ящик в понимании
клиента 334
черный ящик в понимании
производителя 334
штампы проектирования в этой
книге 343
элементы штампа
проектирования 343
список 236, 260, 262, 421, 423
сравнение строк 441
ссылка
объявление 90
подсчет 179
стандартная библиотека шаблонов
29, 259, 421
стандартное исключение 324, 404
стандартные файлы 413
стандартный выходной поток 407
статический
класс памяти 81
член 250, 399
член данных 142
стек 79, 109, 110, 265, 425
LIFO 109
степень многочлена 174
Страуструп, Бьерн 17, 337
строгое соответствие 193
строка 439, 440
как поток 415
поиск строк 442
сравнение строк 441
строковая
библиотека 438
константа 356
строковый
литерал 40
тип 333
структура 21, 107
ch_stack 133, 136
listelem 237
slist 128
имя 108
оператор выбора члена 108
оператор указателя 109
программы 42
ссылающаяся на себя 169
член структуры 107
сужение типа 47
сущность-связь, модель 342
счетчик ссылок 179
Т
таблицы 349, 368, 369, 371, 431, 432,
433, 434
STL: адаптеры функций 437
STL: арифметические объекты
436
STL: библиотечные функции,
связанные с сортировкой 430
STL: библиотечные численные
функции 435
STL: логические объекты 436
STL: сравнивающие объекты
436
STL: функции адаптированного
стека 266, 425
STL: функции адаптированной
очереди 266, 425
STL: функции приоритетной
очереди 425
STL: функции-члены вставки
и удаления 265, 424
STL: функции-члены
распределителей
25. памяти 437, 438
typedef 358
автоинкремент и автодекремент
368
арифметические выражения 368
ассоциативные конструкторы
STL 264, 424
битовый оператор 53, 371
выражения sizeof 367
выражения присваивания 370
глобальные операторы,
перегруженные в string 443
закрытые члены данных класса
string 439
использование ключевого слова
const 357
классы памяти 363
ключевые слова 38, 355
конструкторы класса string 439
манипуляторы ввода-вывода
409
объекты-функции STL 274
объявления 47
объявления и инициализации
220
объявления и присваивания 109
объявления массивов 95
оператор delete 373
оператор new 372
операторы контейнера STL 423
определения ассоциативных
контейнеров STL 264, 423
определения контейнеров STL
261, 422
основные инструкции C++ 375
открытые функции-члены string
441
перечислимые константы 357
поисковые функции-члены
string 442
преобразующая функция
Bctype.h 417
приведения 366
пример строковой константы
356
примеры идентификаторов 354
примеры констант 355
примеры констант
с плавающей точкой 356
приоритет и порядок
выполнения
операторов 367
символьные константы 40, 356
сложность языка 336
стандартные файлы 413
суммирование элементов
массива 90
типы 363
тривиальные преобразования
217
файловые режимы 414
фундаментальные типы данных
44, 362
функции 381
функции и макро в ctype.h 416
функции состояния потока 417
функции-члены STL 424
характеристики функций 396
члены string, перегружающие
операторы 440
члены контейнера STL 261, 422
члены последовательных
контейнеров STL 263, 423
теговое имя 49, 108
тип
bool 362, 368
char* 94
FILE 333
size_t 86
string 440
struct 107
unsigned int 86
void 20, 70
wchar_t 362
автоматическое преобразование
47
возвращаемый функцией 70
идентификация на этапе