Б. Страуструп - Язык программирования С++ (1119446), страница 11
Текст из файла (страница 11)
Приведены конструкции языка, которые существенны длякаждого из перечисленных стилей программирования. Свойственный С стиль программированияобсуждается в разделах "процедурное программирование и "модульное программирование". Язык С++ "лучший вариант С". Он лучше поддерживает такой стиль программирования, чем сам С, причем этоделается без потери какой-либо общности или эффективности по сравнению с С. В то же время язык Cявляется подмножеством С++.
Абстракция данных и объектно-ориентированное программированиерассматриваются как "поддержка абстракции данных" и "поддержка объектно- ориентированногопрограммирования". Первая базируется на возможности определять новые типы и работать с ними, авторая – на возможности задавать иерархию типов.$$1.3 содержит описание основных конструкций для процедурного и модульного программирования. Вчастности, определяются функции, указатели, циклы, ввод-вывод и понятие программы каксовокупности раздельно транслируемых модулей. Подробно эти возможности описаны в главах 2, 3 и 4.$$1.4 содержит описание средств, предназначенных для эффективной реализации абстракции данных.В частности, определяются классы, простейший механизм контроля доступа, конструкторы идеструкторы, перегрузка операций, преобразования пользовательских типов, обработка особыхситуаций и шаблоны типов. Подробно эти возможности описаны в главах 5, 7, 8 и 9.$$1.5 содержит описание средств поддержки объектно-ориентированного программирования.
Вчастности, определяются производные классы и виртуальные функции, обсуждаются некоторыевопросы реализации. Все это подробно изложено в главе 6.$$1.6 содержит описание определенных ограничений на пути совершенствования как языковпрограммирования общего назначения вообще, так и С++ в частности. Эти ограничения связаны сэффективностью, с противоречащими друг другу требованиями разных областей приложения,проблемами обучения и необходимостью трансляции и выполнения программ в старых системах.Если какой-то раздел окажется для вас непонятным, настоятельносоветуем прочитатьсоответствующие главы, а затем, ознакомившись с подробным описанием основных конструкций языка,вернуться к этой главе.
Она нужна для того, чтобы можно было составить общее представление оязыке. В ней недостаточно сведений, чтобы немедленно начать программировать.1.2 Парадигмы программированияОбъектно-ориентированное программирование - это метод программирования, способ написания22Бьерн Страуструп.Язык программирования С++"хороших" программ для множества задач.
Если этот термин имеет какой-то смысл, то он долженподразумевать: такой язык программирования, который предоставляет хорошие возможности дляобъектно-ориентированного стиля программирования.Здесь следует указать на важные различия. Говорят, что язык поддерживает некоторый стильпрограммирования, если в нем есть такие возможности, которые делают программирование в этомстиле удобным (достаточно простым, надежным и эффективным). Язык не поддерживает некоторыйстиль программирования, если требуются большие усилия или даже искусство, чтобы написатьпрограмму в этом стиле. Однако это не означает, что язык запрещает писать программы в этом стиле.Действительно, можно писать структурные программы на Фортране и объектно-ориентированныепрограммы на С, но это будет пустой тратой сил, поскольку данные языки не поддерживают указанныхстилей программирования.Поддержка языком определенной парадигмы (стиля) программирования явно проявляется в конкретныхязыковых конструкциях, рассчитанных на нее.
Но она может проявляться в более тонкой, скрытойформе, когда отклонение от парадигмы диагностируется на стадии трансляции или выполненияпрограммы. Самый очевидный пример - это контроль типов. Кроме того, языковая поддержкапарадигмы может дополняться проверкой на однозначность и динамическим контролем. Поддержкаможет предоставляться и помимо самого языка, например, стандартными библиотеками или средойпрограммирования.Нельзя сказать, что один язык лучше другого только потому, что в нем есть возможности, которые вдругом отсутствуют. Часто бывает как раз наоборот.
Здесь более важно не то, какими возможностямиобладает язык, а то, насколько имеющиеся в нем возможности поддерживают избранный стильпрограммирования для определенного круга задач. Поэтому можно сформулировать следующиетребования к языку:[1]Все конструкции языка должны естественно и элегантно определяться в нем.[2]Для решения определенной задачи должна быть возможность использовать сочетанияконструкций, чтобы избежать необходимости вводить для этой цели новую конструкцию.[3]Должно быть минимальное число неочевидных конструкций специального назначения.[4]Конструкция должна допускать такую реализацию, чтобы в не использующей ее программе невозникло дополнительных расходов.[5]Пользователю достаточно знать только то множество конструкций, которое непосредственноиспользуется в его программе.Первое требование апеллирует к логике и эстетическому вкусу.
Два следующих выражают принципминимальности. Два последних можно иначе сформулировать так: "то, чего вы не знаете, не сможетнанести вам вреда".С учетом ограничений, указанных в этих правилах, язык С++ проектировался для поддержки абстракцииданных и объектно-ориентированного программирования в добавление к традиционному стилю С.Впрочем, это не значит, что язык требует какого-то одного стиля программирования от всехпользователей.Теперь перейдем к конкретным стилям программирования и посмотрим каковы основные конструкцииязыка, их поддерживающие. Мы не собираемся давать полное описание этих конструкций.1.2.1 Процедурное программированиеПервоначальной (и, возможно, наиболее используемой) парадигмой программирования было:Определите, какие процедуры вам нужны; используйте лучшие из известных вам алгоритмов!Ударение делалось на обработку данных с помощью алгоритма, производящего нужные вычисления.Для поддержки этой парадигмы языки предоставляли механизм передачи параметров и получениярезультатов функций.
Литература, отражающая такой подход, заполнена рассуждениями о способахпередачи параметров, о том, как различать параметры разных типов, о различных видах функций(процедуры, подпрограммы, макрокоманды, ...) и т.д. Первым процедурным языком был Фортран, аАлгол60, Алгол68, Паскаль и С продолжили это направление.23Бьерн Страуструп.Язык программирования С++Типичным примером хорошего стиля в таком понимании может служить функция извлеченияквадратного корня. Для заданного параметра она выдает результат, который получается с помощьюпонятных математических операций:double sqrt ( double arg ){// программа для вычисления квадратного корня}void some_function (){double root = sqrt ( 2 );// ..}Двойная наклонная черта // начинает комментарий, который продолжается до конца строки.При такой организации программы функции вносят определенный порядок в хаос различныхалгоритмов.1.2.2 Модульное программированиеСо временем при в проектировании программ акцент сместился с организации процедур наорганизацию структур данных.
Помимо всего прочего это вызвано и ростом размеров программ.Модулем обычно называют совокупность связанных процедур и тех данных, которыми они управляют.Парадигма программирования приобрела вид:Определите, какие модули нужны; поделите программу так, чтобы данные были скрыты в этих модуляхЭта парадигма известна также как "принцип сокрытия данных". Если в языке нет возможностисгруппировать связанные процедуры вместе с данными, то он плохо поддерживает модульный стильпрограммирования. Теперь метод написания "хороших" процедур применяется для отдельных процедурмодуля. Типичный пример модуля - определение стека. Здесь необходимо решить такие задачи:[1]Предоставить пользователю интерфейс для стека (например, функции push () и pop ()).[2]Гарантировать, что представление стека (например, в виде массива элементов) будет доступнолишь через интерфейс пользователя.[3]Обеспечивать инициализацию стека перед первым его использованием.Язык Модула-2 прямо поддерживает эту парадигму, тогда как С только допускает такой стиль.
Нижепредставлен на С возможный внешний интерфейс модуля, реализующего стек:// описание интерфейса для модуля, реализующего стек символов:void push ( char );char pop ();const int stack_size = 100;Допустим, что описание интерфейса находится в файле stack.h, тогда реализацию стека можноопределить следующим образом:#include "stack.h"static char v [ stack_size ];////////используем интерфейс стека``static'' означает локальныйв данном файле/модулестек вначале пустstatic char * p = v;void push ( char c ){//проверить на переполнение и поместить в стек}char pop (){//проверить, не пуст ли стек, и считать из него}24Бьерн Страуструп.Язык программирования С++Вполне возможно, что реализация стека может измениться, например, если использовать для хранениясвязанный список. Пользователь в любом случае не имеет непосредственного доступа к реализации: vи p – статические переменные, т.е.