Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 13
Текст из файла (страница 13)
Эта книга с ее организацией и примерами призвана выстроить такую перспективу. 1.7. Размышления о программировании на С++ В идеале вы разрабатываете программу в три этапа. Сначала вы добиваетесь ясного понимания задачи (анализ), затем определяете ключевые концепции, в терминах которых выражается решение задачи Гпроектировацие), и, наконец, воплощаете решение в программе Гпрограммирование). Однако детали проблемы и некоторые аспекты решения часто становятся понятными только в процессе написания программы и при попытках заставить ее работать. Тогда-то и становится важным выбор языка.
В большинстве приложений существуют понятна, которые пе просто представить в виде предопределенного типа или функции без связанных с ней данных, Если такое понятие есть, объявите класс, представляющий это понятие в программе. Класс в С ' -' — это тип. Он описывает поведение объектов этого класса: как они создаются, управляются и уничтожаются. Класс также может определять представление объектов, хотя на ранних стадиях проектирования это пе должно быть главной заботой, Ключом к проектированию хороших программ является выделение классов, каждый из которых ясно описывает отдельное понятие. Часто зто означает, что вы должны сосрелоточиться на вопросах типа; «Как создаются объекты класса? Можно ли объекты этого класса копировать и/или уничтожать? Какие операции можно применять к объектам класса?». Если па эти вопросы нет хороших ответов, вероятно нет и ясно~о понимания самих понятий.
Возможно, стоит еще раз подумать о задаче и предлагаемых решениях, а не кидаться программировать. Легче всего работать с традиционными математическими понятиями: всевозможными числами, множествами, геометрическими фигурами н т. п. Текстовый ввод/вывод, строки, основные контейнеры, базовые алгоритмы, применяемые для обработки таких контейнеров, и некоторые математические классы являются частью стандартной библиотеки С««(глава 3, з 16.1.2). Кроме того, существует огромное количество библиотек поддержки общих и узкоспециальных понятий. Понятия существуют не в вакууме, они всегда объединяются в группы.
Часто сложнее организовать отношения между классами в программе (то есть точно определить отношения между различными понятиями, используемыми в решении), чем отдельные классы. Лучше избегать путаницы, когда каждый класс (понятно) связан со всеми другими. ГГредставьте два класса А и В.
Отношения типа «А вызывает функцию из В>, «А создает объекты В» и «объект типа В является членом А» редко вызывают ссрьезныс проблемы, в то время как отношений типа «А использует данные В» обычно следует избегать. Одним нз мощнейших интеллектуальных инструментов преодоления сложности является иерархическое упорядочивание, то есть организация связанных понятий в древообразную структуру с наиболее общим понятием в корне.
В С' производные классы представляют именно такую структуру. Программа часто может быть организована в виде набора деревьев или ориентированных графов классов, не содержащих циклы, То есть программист определяет ряд базовых классов, каждый пз которых имеет набор производных классов. Для определения операций с наиболее общими 52 Глава 1. Обращение к читателю понятиями (операций базовых классов) часто можно воспользоваться виртуальными функциями Я 2.5.5, з 12.2.6). Затем в конкретных случаях интерпретация этих операций может быть переопределена в производных классах.
Иногда даже ориентированного графа без циклов недостаточно для организации понятий в программе. Некоторые понятия изначально взаимно зависимы. В таких ситуациях мы пытаемся локализовать циклические зависимости так, чтобы онн не влияли на структуру программы в целом. Если вам не удается избавиться от таких зависимостей или локализовать их, то, похоже, вы находитесь в тупике, выбраться из которого не поможет пи один язык программирования. Если вам не удается добиться относительно просто формулируемых отношений между основными понятиями, программа имеет все шансы стать неуправляемой.
Одним из лучших способов развязывания зависимостей является отчетливое разграничение интерфейса и реализации. Основным инструментом для этого в С«+ является абстрактный класс Я 2.5. ц ~ 12.3). Другая форма общности может быть выражена прн помощи шаблонов Ц 2.7, глава 13). Шаблон класса определяет семейство классов. Например, шаблон списка определяется как «список объектов типа Т», где «Т» может быть любым типом. Таким образом, шаблон — это механизм создания типа, которому другой тип передается в качестве ар|умецта. Наиболее распространенными шаблонами являются классы контейнеров (такие как списки, массивы, ассоциативные массивы) и основные алгоритмы, использующие эти контейнеры.
Выражение зависимости класса н связанных с ним функций от типа с использованием механизма наследования обычно является ошибкой. Лучше использовать шаблоны. Помните, что большую часть работы можно просто и понятно выполнить с использованием только примитивных типов, структур данных, обычных функций н нескольких библиотечных классов. Не стоит использовать полный аппарат определения новых типов, если в этом нет действительной необходимости. Вопрос «Как писать хорошие программы на С+»?» напоминает вопрос «Как писать хорошую английскую прозу?».
Есть два совета: «Знай, что хочешь сказать» и «Тренируйся. Подражай хорошему стилго». Оба совета годятся как для С+«, так и для английской прозы, и им обоим одинаково сложно следовать. 1.8. Советы Вот набор «правил», которые могут пригодиться при изучении С++. По мере продвижения вы сможете развить их в некую более осмысленную концепцию, соответствующую вашим задачам и вашему стилю программирования.
Оци намеренно упрощены и поэтому детали опущены. Не воспринимайте их буквально. Для написания хороших программ требуется ум, вкус и терпение. Не ожидайте, что у вас хорошо получится с первого раза. Экспериментируйте! 11) В процессе про~ раммирования вы воплощаете свое решение некоторой задачи в конкретный код. Постарайтесь, чтобы структура программы отражала ваши идеи как можно более непосредственно: 1а1 Если вы думаете об «этом» как об отдельном понятии, оформите «это» в виде класса.
1Ъ1 Если вы думапге об «этом» как об отдельной сущности, сделайте «это» объектом какого-нибудь класса. 58 1.8. Советы [с] Если два класса имеют общий интерфейс, оформите этот интерфейс в виде абстрактного класса. [с]] Если реализации двух классов имеют нечто существенно общее, реализуйте это общее в виде базового класса. [е] Если класс является контейнером объектов, сделайте из него шаблон.
[!] Если функция реализует алгоритм для контейнера, оформите ее в виде шаблона функции, выполняющего алгоритм для семейства контейнеров. [8] Если классы, шаблоны и т. п. логически связаны между собой, поместите их в одно пространство имен. [2] Какой бы класс вы не определяли (если только он не реализует математические сущности вроде матриц, комплексных чисел или низкоуровневые типы наподобие связанного списка): [а] Не используйте глобальные данные (пользуйтесь членами). [Ъ] Не используйте глобальные функции. [с] Не используйте открытые члены класса.
[г]] Не используйте функций-друзей, разве что во избежание [а] или [с], [е] Не создавайте в классе «поля тип໠— пользуйтесь виртуальными функциями. [!] Не применяйте встроенные функции, разве что для значительной оптимизации. Более специфические или подробные правила вы найдете в советах в конце каждой главы. Помните, что зто всего лишь рекомендации, а нс непреложные законы. Советами нужно пользоваться там, где они применимы.
Не существует замены уму, опыту, здравому смыслу и хорошему вкусу. Я считаю, что правила типа «никогда не делай это» бесполезны. Поэтому большинство советов построено в форме предложений типа «что делать», а негативные утверждения выражены без оттенка абсолютного запрета. Я ре знаю ни одного существенного средства С++, примеры качественного использования которого мне никогда бы не встречались. Раздел «Советы» не содержит объяснений. Вместо них за каждым советом следует ссылка на соответствующий раздел книги. Если совет выражен в негативной форме, в указанном разделе приведены позитивные альтернативы. 1.8.1.
Литература В тексте мало прямых ссылок; ниже приводится список книг и статей, упомянутых прямо или косвенно. [Вэггоп, 1994] ]оЬп ]. Ваггоп апб 1 ес В. Хасйшап: Вс1епгй"!с ииг! Еп8!пес~!щ С+». Ай !эоп-Жеэ!еу, Веайпй, Маээ. 1994. 18ВХ 1-20!-53393-6. [Вегй, 1995] ЪЧ!!!!аш Вегй, МагэЬа!! С11пе, апг] М1йе О!гоп: ьеээопх!еаглег( (гот ГЬе 05 '400 00 Рго1есй САСМ.
Чо!. 38 Хо. 10. ОсгоЪег 1995. [ВоосЬ, 1994] Сгаг]у ВоосЬ; ОЬ>есГ-Ог!елэег( Ала!уэйэ апй Оеэ!8п. Веп]аш1п/ Спппп!пйэ. Меп1о Рагй, СаИ 1994. 1ЗВХ 0-8053-5340-2, [Впг]йе, 1992] Кепс Впдяе, ]. 8. Реггу, апс] А. С. ВоЪ1пэоп: Н(8Ь-Рег~огталсе 5аептугс Сотригайоп ипля С++, Ргос. (!ЗЕХ1Х С++ Соп!егепсе.
Рог!!апд, Оге8оп. Ап8пзг 1992. [С, 1990] . ХЗ Зесгегайап 5гаийагй — ТБе С! ипбиа8к ХЗ]11/90-013. 180 Згапоагп !50/!ЕС 9899. Сошрцтег апб Впейпеэз Ес!и!ршеп! Мапп(асгпгегэ Аээос!аг!оп. ууаэЬ!пйсоп, ПС, УЗА. 54 Глава |. Обращение к читателю [Сч-ч-,1998] [Сев. 2003] [СатрЬеП, 1987] [СорПеп, 1995] [ОаЫ, 19?О] [ОаЫ, 1972] [ЕПЬ, 1989] [Сапипа, 1995] [Со!ЛЬегд, 1983] [Сгсычо!г[, 1970] [Нави1|ов, 1993] [СгЬгчо!й 1983] [Нспгкьоп, 1997] [1сЬЬгап, 19?9] [Ка|па|Ь, 1993] [Кегт!дЬап, 1978] [Кегп|дЬап, 1988] [Коешд, 1989] ХЗ десгссаНас: !л|етпаг|ола1 5салг)агг1 — ТАе С ч- ?.апдиаде. ХЗД16-14882.
1п!оппас|оп ТесЬпо1оду Соиле|! (1981ТС). ЪЪгаьЬ1вдсоп, Г)С, 1)5А. ХЗ ЗесгесаНаС: !псегпаг|ола! 5сапг!агг! — Тле О++ !.апдиаде (|п- о!ийпд сЬс 2003 ТесЬшса! Согпдепднп|). 14882:2003(Г). 1п1ог- тас!оп ТесЬпо!оду СоипсП (!з!81ТС). ЪЪгаьЬ1пдсоп, ОС, 1)ВА.
В.оу СатрЬеП, сс а!з Т)зе Вез!дп о! а Ми)1!ргосеззог Орегагтд 5узгвт. Ргос. УЯЕ!ч!1Х С з+ Сол1сгепсе. Запса Ре, !з)ечч Мсхко. Ыочев|!зсг 1987. )а|вез О. Сор!|еп апг[ Ооид!аь С. ЗсЬтйс (ейсогь): Раггегп Тапдиадез оу" Ргодгат ?)ез(дп. Аг!Йьоп-з?згез!еу, )зеаг[!вд, Мазь. 1995, 1ВВ!|1 1-201-60?34-4. О-[. РаЫ, В. МугЬас|д, апг[ К. !чудаагг[: 5ТМИА Сот топ Вазе Гапдиаде. Ь!огччод!ап Сот рибпд Сепсег Я-22. Оь!о, 1з1огзчау. 1970 0-], ОаЫ авг[ С. А. Гз.