Штерн В. - Основы C++. Методы программной инженерии - 2003
.pdf
|
С о в е т у е м Особенно полезные сведения, помогающие читателям |
^ж |
сэкономить время, ценные рекомендации по программированию |
или какие-либо конкретные советы для более продуктивной работы. |
Доступ к исходному коду
в процессе изучения языка очень важно применять полученные знания на практике. Осваивать С++ без практики — все равно, что учиться вождению без автомобиля. Можно усвоить массу полезных сведений, но водить автомобиль так и не научиться. Автор настоятельно рекомендует поэкспериментировать с про граммами, обсуждаемыми в данной книге. Исходный код со всеми листингами можно найти на сайте:
f t p : / / f t p . prenhall. com/pub/ptr/c++programming. w-050/corec++
Обратная связь
Данная книга тщательно выверена и отредактирована. Тем не менее в ней могут содержаться некоторые ошибки.
Автор старался написать уникальную книгу, и, возможно, читатели встретят здесь утверждения, которые покажутся им безосновательными, неоправданными или просто ошибочными, противоречивыми и требуюш^ими обсуждения.
Если у вас будут какие-нибудь замечания или дополнения, пишите по адресу: shtern@bu.eclu
Содержание
Благодарности |
vi |
Предисловие |
vii |
Часть I
Введение в программирование на C++
Глава 1 Объектно-ориентированный подход: что это такое! |
3 |
Истоки кризиса программного обеспечения |
4 |
Выход первый: избавиться от программистов |
7 |
Выход второй: совершенствование методов управления |
9 |
Метод "водопада" |
9 |
Быстрое прототипирование |
10 |
Выход третий: разработка сложного и подробного языка |
11 |
Объектно-ориентированный подход: что он дает и какой ценой? |
12 |
Чем занимается проектировщик? |
13 |
Качество проекта: сцепление |
14 |
Качество проекта: связность |
14 |
Качество проекта: связывание вместе данных и функций |
15 |
Качество проекта: сокрытие информации и инкапсуляция |
17 |
Проблемы проектирования: конфликты имен |
18 |
Проблемы проектирования: инициализация объектов |
18 |
Так что же такое объект? |
19 |
Преимущества применения объектов |
20 |
Характеристики языка программирования C++ |
21 |
Цели языка С: производительность, удобочитаемость, красота и переносимость- |
• 21 |
Цели языка C++: классы и обратная совместимость с языком С |
23 |
Итоги |
25 |
Глава 2 Быстрый старт: краткий обзор C + + |
27 |
Базовая структура программы |
28 |
Директивы препроцессора |
30 |
Комментарии |
33 |
Описания и определения |
36 |
Операторы и выражения |
41 |
Функции и вызовы функций |
47 |
Классы |
55 |
Применение инструментальных средств разработки |
|
программного обеспечения |
58 |
Итоги |
62 |
XII |
Содержание |
|
|
Глава 3 |
Работа с данными и выражениями C + + |
|
63 |
|
Значения и их типы |
|
63 |
|
Интегральные типы |
|
66 |
|
Спецификаторы типов |
|
67 |
|
Символы |
|
71 |
|
Булевы значения |
|
73 |
|
Типы с плавающей точкой |
|
73 |
|
Работа с выражениями C++ |
|
75 |
|
Высокоприоритетные операции |
|
76 |
|
Арифметические операции |
|
77 |
|
Операции сдвига |
|
79 |
|
Поразрядные логические операции |
|
80 |
|
Операции отношения и равенства |
|
82 |
|
Логические операции |
|
84 |
|
Операции присваивания |
|
85 |
|
Условная операция |
|
87 |
|
Операция запятой |
|
87 |
|
Смешанные выражения: скрытая опасность |
|
88 |
|
Итоги |
|
93 |
Глава 4 |
Управление ходом выполнения программы C + + |
|
95 |
|
Операторы и выражения |
|
96 |
|
Условные операторы |
|
97 |
|
Стандартные формы условных операторов |
|
97 |
|
Распространенные ошибки в условных операторах |
|
101 |
|
Вложенные условные операторы и их оптимизация |
|
110 |
|
Итерация |
|
117 |
|
Применение цикла while |
|
117 |
|
Итерации в цикле do-while |
|
124 |
|
Итерации с циклом for |
|
127 |
|
Операторы перехода в C++ |
|
130 |
|
Оператор break |
|
131 |
|
Оператор continue |
• |
133 |
|
Оператор goto |
• |
• 134 |
|
Переходы return и exit • • |
• • • • 135 |
|
|
Оператор switch |
|
139 |
|
Итоги |
|
142 |
Глава 5 |
Агрегирование с помощью типов данных, |
|
|
|
определяемых программистом |
|
143 |
|
Массивы как однородные агрегаты |
|
144 |
|
Массивы как векторы значений |
|
144 |
|
Определение массивов в C++ |
|
145 |
|
Операции с массивами |
|
147 |
|
Проверка допустимости индекса |
|
148 |
|
Многомерные массивы |
|
151 |
|
Определение символьных массивов |
|
154 |
|
Операции с символьными массивами |
|
155 |
|
Строковые функции и порча содержимого памяти |
|
156 |
|
Двумерные символьные массивы |
|
160 |
|
|
Содержание |
I |
xiii P |
|
Переполнение массива в алгоритме вставки |
|
162 |
|
|
Определение типов массивов- |
|
|
165 |
|
Структуры как неоднородные агрегаты |
|
167 |
|
|
Структуры, определяемые программистом |
|
167 |
|
|
Создание и инициализация переменных-структур |
|
168 |
|
|
Иерархические структуры и их компоненты |
|
159 |
|
|
Операции с переменными-структурами |
|
170 |
|
|
Определение структур в многофайловых программах |
|
172 |
|
|
Объединения, перечисления и битовые поля |
|
173 |
|
|
Объединения |
|
|
173 |
|
Перечисления |
|
|
176 |
|
Битовые поля |
|
|
179 |
|
Итоги |
|
|
182 |
Глава 6 |
Управление памятью: |
|
|
|
|
стек и динамически распределяемая область |
|
183 |
|
|
Область действия имени как средство кооперации |
|
184 |
|
|
Лексические области действия в C++ |
|
- 184 |
|
|
Конфликты имен в одной области действия |
• |
• 185 |
|
|
Использование одинаковых имен в независимых областях действия |
|
188 |
|
|
Использование одинаковых имен во вложенных областях действия |
|
189 |
|
|
Область действия переменных цикла |
|
193 |
|
|
Управление памятью: классы памяти • • • |
|
193 |
|
|
Автоматические переменные |
|
|
195 |
|
Внешние переменные |
|
|
197 |
|
Статические переменные |
|
|
202 |
|
Управление памятью: использование динамически распределяемой области 206 |
|||
|
Указатели C++ как типизированные переменные |
|
207 |
|
|
Выделение памяти в динамической области |
|
212 |
|
|
Массивы и указатели |
|
|
215 |
|
Динамические массивы |
|
|
218 |
|
Динамические структуры |
|
|
230 |
|
Обмен данными с файлами на диске |
|
239 |
|
|
Вывод в файл |
|
|
239 |
|
Ввод из файла |
|
|
241 |
|
Файловые объекты ввода и вывода |
|
245 |
|
|
Итоги |
• |
|
248 |
Часть II
Объектно-ориентированное программирование на С++
Глава 7 Программирование с использованием функций C + + |
253 |
Функции C++ как средства разбиения программы на модули |
254 |
Объявление функции |
255 |
Определения функций |
256 |
Вызовы функций |
257 |
Преобразование типов аргументов |
258 |
XIV |
|
|
|
|
Передача параметров в C++ |
|
260 |
|
Передача по значению |
|
260 |
|
Вызов по указателю |
|
262 |
|
Передача параметров в C++ по ссылке |
268 |
|
|
Структуры |
|
271 |
|
Массивы |
|
276 |
|
Еще о преобразовании типов |
|
279 |
|
Возврат значения из функции |
|
281 |
|
Встраиваемые функции |
|
287 |
|
Параметры с заданными по умолчанию значениями |
289 |
|
|
Перегрузка имен функций |
|
293 |
|
Итоги |
|
300 |
Глава 8 |
Объектно-ориентированное |
программирование |
|
|
с использованием функций |
|
302 |
|
Сцепление |
|
305 |
|
Связность |
• |
305 |
|
Неявная связность |
|
306 |
|
Явная связность |
|
309 |
|
Как уменьшить степень связности |
313 |
|
|
Инкапсуляция данных |
|
317 |
|
Сокрытие информации |
|
322 |
|
Большой пример инкапсуляции |
|
327 |
|
Недостатки инкапсуляции с использованием функций |
335 |
|
|
Итоги |
|
337 |
Глава 9 |
Классы C + + как единицы модульности программы |
339 |
|
|
Базовый синтаксис класса |
|
341 |
|
Связывание операций и данных |
•* • • 341 |
|
|
Исключение конфликтов имен |
|
345 |
|
Реализация функций-членов вне класса |
348 |
|
|
Определение объектов классов с разными классами памяти |
351 |
|
|
Управление доступом к компонентам класса |
352 |
|
|
Инициализация экземпляров объекта • • |
357 |
|
|
Конструкторы как функции-члены |
358 |
|
|
Конструкторы, используемые по умолчанию |
360 |
|
|
Конструкторы копирования |
|
362 |
|
Конструкторы преобразования |
|
364 |
|
Деструкторы |
|
366 |
|
Время вызова конструктора и деструктора |
370 |
|
|
Область действия класса и подмена имен во вложенных областях |
370 |
|
|
Управление памятью с помощью операций и вызовов функций |
372 |
|
|
Использование в коде клиента возвращаемых объектов |
376 |
|
|
Возврат указателей и ссылок |
|
376 |
|
Возврат объектов |
|
378 |
|
Еще о ключевом слове const |
|
381 |
|
Статические компоненты класса |
• • • • |
386 |
|
Применение глобальных переменных как характеристик класса |
386 |
|
|
Четвертый смысл ключевого слова static |
388 |
|
|
С о д е р ж а н и е |
XV |
|
Инициализация статических элементов данных |
389 |
|
Статические функции-члены |
390 |
|
Итоги |
393 |
Глава 10 |
Операторные функции |
394 |
|
Перегрузка операций |
395 |
|
Ограничения перегрузки операций |
402 |
|
Какие операции не могут быть перегруженными |
402 |
|
Ограничения на возвращаемые типы |
404 |
|
Ограничения на число параметров |
405 |
|
Ограничение на старшинство операций |
406 |
|
Перегруженные операции как компоненты класса |
406 |
|
Замена глобальной функции компонентом класса |
407 |
|
Использование членов класса для цепочек операций |
409 |
|
Применение ключевого слова const |
410 |
|
Учебный пример: рациональные числа |
412 |
|
Параметры смешанных типов |
420 |
|
Дружественные функции |
427 |
|
Итоги |
438 |
Глава 11 |
Конструкторы и деструкторы: потенциальные п р о б л е м ы |
440 |
|
Передача объектов по значению |
441 |
|
Перегрузка операций для нечисловых классов |
446 |
|
Класс String |
446 |
|
Динамическое управление памятью |
448 |
|
Защита данных объекта от клиента • • • • |
451 |
|
Перегруженная операция конкатенации |
451 |
|
Предотвращение "утечек памяти" |
453 |
|
Защита целостности программы |
454 |
|
Переход из пункта А в пункт В |
458 |
|
Конструктор копирования |
459 |
|
Решение проблем целостности |
460 |
|
Семантика копирования и семантика значений |
464 |
|
Конструктор копирования, определяемый программистом |
465 |
|
Возврат по значению |
469 |
|
Ограничения для эффективности конструктора копирования |
472 |
|
Перегрузка операции присваивания |
472 |
|
Проблемы системной операции присваивания |
473 |
|
Перегруженная операция присваивания: первая версия (утечка памяти) • • |
• • 473 |
|
Перегруженная операция присваивания: следующая версия |
|
|
(самоприсваивание) |
475 |
|
Перегруженная операция присваивания: еще одна версия |
|
|
(цепочка выражений) |
475 |
|
Вопросы производительности |
478 |
|
Первое решение: больше перегруженных операций |
479 |
|
Второе решение: возврат по ссылке |
480 |
|
Практические вопросы: что подлежит реализации |
481 |
|
Итоги |
484 |
XVI Содержание
Часть III
Объектно-ориентированное программирование с агрегированием и наследованием
Глава 12 Преимущества и недостатки составных классов |
487 |
Использование объектов классов как элементов данных |
488 |
Синтаксис C++ для композиции класса |
490 |
Доступ к элементам данных элементов данных класса |
492 |
Доступ к элементам данных параметров метода |
494 |
Инициализация составных объектов |
495 |
Применение используемых по умолчанию конструкторов компонента |
497 |
Использование списка инициализации элементов |
502 |
Элементы данных со специальными свойствами |
507 |
Константы как элементы данных |
507 |
Ссылочные элементы данных |
508 |
Использование объектов как элементов данных |
|
своего собственного класса |
511 |
Использование статических элементов данных |
|
как компонентов собственного класса |
513 |
Контейнерные классы |
515 |
Вложенные классы |
529 |
"Дружественные" классы |
531 |
Итоги |
534 |
Глава 13 Подобные классы и их интерпретация |
|
|
|
535 |
Интерпретация подобных классов |
|
|
|
537 |
Слияние свойств подклассов в один класс |
|
|
|
538 |
Перенос ответственности за целостность программы на сервер |
|
|
|
539 |
Отдельные классы для каждого серверного объекта |
|
|
|
544 |
Применение наследования C++ для связывания родственных классов |
|
|
|
546 |
Синтаксис наследования в C++ |
|
|
|
549 |
Различные режимы создания производного класса из базового класса • |
• |
• |
• |
550 |
Определение и использование объектов базовых и производных классов |
• |
• |
• |
553 |
Доступ к сервисам базового и производного классов |
|
|
|
555 |
Доступ к базовым компонентам объекта производного класса |
|
|
|
558 |
Наследование компонентов public |
|
|
|
559 |
Наследование в режиме protected |
|
|
|
563 |
Наследование в режиме private |
|
|
|
567 |
Изменение доступа к компонентам базового класса в производном классе |
• |
• |
569 |
|
Режим наследования по умолчанию |
|
|
|
570 |
Правила области действия и разрешение имен при наследовании |
|
|
|
572 |
Перегрузка и сокрытие имен |
|
|
|
574 |
Вызов метода базового класса, скрытого производным классом |
|
|
|
578 |
Применение наследования для развития программы |
|
|
|
581 |
Конструкторы и деструкторы для производных классов |
|
|
|
584 |
Использование в конструкторах производных классов |
|
|
|
|
списков инициализации |
|
|
|
587 |
Деструкторы при наследовании |
|
|
|
590 |
Итоги |
|
|
|
592 |
Содержание |
XVII |
Глава 14 Выбор между наследованием и композицией |
593 |
Выбор методики повторного использования кода |
594 |
Пример связи "клиент-сервер" между классами |
595 |
Повторное использование результатов интеллектуальной деятельности • |
• • 598 |
Повторное использование посредством покупки сервисов |
600 |
Повторное использование программы с помощью наследования |
603 |
Наследование в повторно определенных функциях |
608 |
Достоинства и недостатки наследования и композиции |
610 |
Унифицированный язык моделирования |
611 |
Цели использования UML |
611 |
Основы UML: нотация обозначений для классов |
614 |
Основы UML: нотация для связей |
615 |
Основы UML: нотация для агрегации и обобщения |
616 |
Основы UML: нотация для множественности |
618 |
Учебный пример: магазин проката |
619 |
Классы и их ассоциации • • • |
620 |
Видимость класса и разделение обязанностей |
634 |
Видимость класса и связи классов |
635 |
Принудительная передача обязанностей серверным классам |
636 |
Использование наследования |
638 |
Итоги |
640 |
Часть IV
Расширенное использование C++
Глава 15 Виртуальные функции |
|
и прочее расширенное использование наследования |
643 |
Преобразования несвязанных классов |
645 |
Строгий и слабый контроль типов |
647 |
Конструкторы преобразования |
648 |
Приведение указателей |
650 |
Операторы преобразования |
650 |
Преобразование классов, связанных наследованием |
651 |
Безопасные и опасные преобразования |
651 |
Преобразование указателей и ссылок в объекты |
656 |
Преобразование аргументов указателя и ссылки |
663 |
Виртуальные функции |
668 |
Динамическое связывание: традиционный подход |
671 |
Динамическое связывание: объектно-ориентированный подход |
678 |
Динамическое связывание: виртуальные функции |
686 |
Динамическое и статическое связывание |
691 |
Чисто виртуальные функции |
693 |
Виртуальные функции: деструкторы |
697 |
Множественное наследование: несколько базовых классов |
699 |
Множественное наследование: правила доступа |
700 |
Преобразования классов |
702 |
Множественное наследование: конструкторы и деструкторы |
703 |
XVIII |
Содержание |
|
|
|
Множественное наследование: неоднозначность |
704 |
|
|
Множественное наследование: ориентированный граф |
706 |
|
|
Полезно ли множественное наследование |
708 |
|
|
Итоги |
• |
709 |
Глава 16 |
Расширенное использование перегрузки операций |
711 |
|
|
Перегрузка операций: краткий обзор |
711 |
|
|
Унарные операции |
|
719 |
|
Операции инкремента и декремента |
719 |
|
|
Постфиксные перегруженные операции |
727 |
|
|
Операции преобразования |
|
729 |
|
Операции, возвращающие компонент массива по индексу, |
|
|
|
и операции вызова функции |
|
736 |
|
Операции, возвращающие компонент массива по индексу |
737 |
|
|
Операция вызова функции |
|
745 |
|
Операции ввода/вывода |
|
750 |
|
Перегрузка операции >> |
|
750 |
|
Перегруженная операция « |
|
754 |
|
Итоги |
|
756 |
Глава 17 |
Шаблоны как е щ е одно средство проектирования |
757 |
|
|
Простой пример повторного использования структуры класса |
758 |
|
|
Синтаксис определения шаблонного класса |
766 |
|
|
Спецификация шаблонного класса |
766 |
|
|
Реализация шаблона |
|
768 |
|
Реализация шаблонных функций |
|
769 |
|
Вложенные шаблоны |
|
775 |
|
Шаблонные классы с несколькими параметрами |
776 |
|
|
Несколько параметров типов |
|
777 |
|
Шаблоны с параметрами — константные выражения |
779 |
|
|
Взаимосвязи между реализациями шаблонных классов |
782 |
|
|
Шаблонные классы как "друзья" |
|
783 |
|
Вложенные шаблонные классы • • |
786 |
|
|
Шаблоны со статическими компонентами |
788 |
|
|
Специализации шаблонов |
|
790 |
|
Шаблонные функции |
|
794 |
|
Итоги |
|
796 |
Глава 18 |
Программирование с о б р а б о т к о й исключительных ситуаций |
797 |
|
|
Простой пример для обработки исключительных ситуаций |
798 |
|
|
Синтаксис исключительных ситуаций C++ |
804 |
|
|
Генерация исключительной ситуации |
805 |
|
|
Отслеживание исключительной ситуации |
806 |
|
|
Обозначение исключительной ситуации |
812 |
|
|
Повторная генерация исключительной ситуации |
815 |
|
|
Исключительные ситуации с объектами класса |
• • • 817 |
|
|
Синтаксис объектов генерации, обозначения и отслеживания |
818 |
|
|
Использование наследования с исключительными ситуациями |
821 |
|
|
Стандартная библиотека исключительных ситуаций |
825 |
|
|
Содержание |
XIX |
Операции приведения типов |
827 |
|
Операция static_cast |
827 |
|
Операция |
reinterpret_cast |
831 |
Операция const_cast |
831 |
|
Операция dynamic_cast |
834 |
|
Операция typeid |
836 |
|
Итоги |
|
837 |
Глава 19 Полученные у р о к и |
839 |
|
C + + к а к традиционный язык программирования |
840 |
|
Встроенные типы данных C++ |
840 |
|
Выражения C++ |
842 |
|
Управляющая логика в C++ |
843 |
|
C++ как модульный язык |
844 |
|
Составные типы C++: массивы |
844 |
|
Составные типы C++: структуры, объединения, перечисления |
845 |
|
Функции C++ как средства обеспечения модульности |
846 |
|
Функции C++: передача параметров |
848 |
|
Область видимости и класс памяти в C++ |
849 |
|
C++ как объектно-ориентированный язык |
850 |
|
Классы C++ |
850 |
|
Конструкторы, деструкторы и перегруженные операции |
851 |
|
Композиция классов и наследование |
853 |
|
Виртуальные функции и абстрактные классы |
854 |
|
Шаблоны |
|
855 |
Исключительные ситуации |
856 |
|
C++ и его конкуренты |
857 |
|
C++ и старшие языки |
857 |
|
C++ и Visual Basic |
857 |
|
C++ и С |
|
858 |
C++ и Java |
|
859 |
Итоги |
. ; . . . . |
860 |
