Б. Страуструп - Дизайн и Эволюция C++. 2006, страница 9
Описание файла
DJVU-файл из архива "Б. Страуструп - Дизайн и Эволюция C++. 2006", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр DJVU-файла онлайн
Распознанный текст из DJVU-файла, 9 - страница
Это соображение (если хотите, принцип) приходилось снова ПИИИИИИВ Язык С алФ С!аззез и снова повторять тем людям (как правило, не работавшим постоянно с С ъчгЬ С!аззез), которые хотели слелать версию безопаснее, введя статический контроль типов а-ля Разса1. Альтернативу такой «безопасности» вЂ” вставку проверок в исполняемый код — решили реализовывать в отладочных срелах. В самом языке нельзя было организовывать таких проверок, ибо тогда он бсзналежно проиграл бы С по скорости и расхолу памяти. Поэтому такого рода контроль в С пчгЬ С!аззсз включен не был, хотя в некоторых срелах разработки лля С++ он имеется, но только в отлалочном режиме.
Кроме того, пользователи могут сами произволить проверки во время выполнения там, где сочтут целесообразным (см, разлел 16.10 и !2пд]). С полдержнвает низкоуровневые операции, например манипуляции с битами и выбор межлу разными размерами целых. Имеются в нем и такие средства (допустим, явное преобразование типов), которые позволяют намеренно обойти систему контроля типов. С Ъ%1Ь С!аззез, а затем и С++ сохранили низкоуровневые и небезопасные особенности С.
Но в С++ систематически устраняется необхолимость использования таких срелств за исключением тех мест, где без них никак не обойтись. При этом небезопасные операции выполняются только по явному указанию программиста. Я искренне убежлен, что не существуст единственно правильного способа написать программу, и лизайнер языка не лолжен заставлять программиста слеловать определенному стилю. С другой стороны, дизайнер обязан всячески полдерживать все разнообразие стилей и способов программирования, доказавших свою эффективность, а равно предоставить такие языковые возможности и инструментальные средства, которые уберегли бы программиста от хорошо известных ловушек. 22. Обзор языковых возможностей Вот сводка тех срелств, которые были включены в первую версию 1980 гс ш классы (разлел 2.3); д производные классы (но пока без виртуальных функций, раздел 2.9); а контроль доступа — открытый/закрытый (разлел 2.10); я конструкторы и деструкторы (разлел 2.11.1); д функции, вызываемые при вызове и возврате (позже исключены, раздел 2.11.3); и дружественные (ггхепс1) классы (раздел 2.10); ш контроль и преобразование типов аргументов функции (раздел 2.6).
В 1981 г.добавлены: я встраиваемые (1п!!пе) функции (разлел 2.4.1); а аргументы по умолчанию (раздел 2.12.2); ш перегрузка оператора присваивания (раздел 2.12 1). Поскольку С тч11Ь С1аззез был реализован с помощью препроцессора, описывать слеловало лишь новые, отсутствовавшие в С возможности, а вся мощь С и так оставалась в распоряжении пользователей.
В то время оба зти аспекта были лолжным образом оценены. Раз С вЂ” подмножество языка, то объем работы по поддержке и локументированию намного уменыпастся. Это особенно важно, поскольку на ИИИИИИИП Классы 2.3. КЛаССЫ Очевидно, самой важной чертой С тч)гЬ С)аваев, а позже и С++ была концепция класса. Многие ее аспекты видны из слелуюшего примера [Бггоцвггцр, 1980['. с1авв агаси ( спаг в(Б12В); массив символов */ спаг* вьп; указатель на конец стека */ с)гаг* Гор; указатель на вершину стека */ спаг* вак; указатель на начало выделенной области */ човг) пеы(); функция инициализации (конструктор) */ рц)з11с: чоЫ рцвп(с)гаг]; спаг рор()г ); Класс — это опрелеленный пользователем тип данных.
Он содержит описания типов членов класса, то есть представление переменной данного типа (объекта класса), и набор операций (функций) для манипулирования такими объектами. Класс также опрелеляет права доступа к своим членам со стороны пользователей. Функции-члены обычно опрелеляются отлельно: /* /* /* /* /* сьаг всасх.рор() ( 11 (гор <= вфл) еггог("стек пуст"); гегыгп *(--гор); ) Теперь можно определить и использовать объекты класса всас)с( /* две переменные типа агаси */ /* р1 указывает на в2 */ с1авв агаси в1, в2г с1авв вгас)г * р1 = ав2; ' Я сохранил оригинальный синтаксис и стиль С впйЬ С)аваев.
Отличия от С++ и современного стиля кодирования вряд ли у кого-то вызовут затруднения, а некоторым читателям будут интересны. Однако очевидные ляпы исправлены. Также добавлены комментарии, которых в нсхолном тексте не было. протяжении нескольких лет мне приходилось заниматься документированием и подлержкой С цг!1Ь С!аваев и С++ олновременно с экспериментированием, проектированием и реализацией новых версий.
Доступность всех возможностей С гарантировала, что по нелосмотру или из-за моих предрассудков не булет введено никаких ограничений, которые лишат пользователей привычных средств. Естественно, переносимость на машины, где С уже имелся, обеспечивалась автоматически. Изначально С впгЬ С! аваев был реализован и эксплуатировался на ВЕС РЕ)Р/11, но вскоре был перенесен на Е)ЕС 1/АХ и компьютеры на базе процессора Мотого!а 68000.
С тч!1Ь С!аваев все еше рассматривался как диалект С, а не как самостоятельный язык. Даже классы тогла назывались еабстрактными типами данных (аЬзсгасг (!ага туре (ас!1(гу)» [Бггоцвггпр, 1980!. Подлержка объектно-ориентированного программирования была провозглашена лишь после лобавления в С++ виртуальных функций [Бтгоцвтгар, 1984]. ИИИИИИИИ Язык С (/)/1Ф С!аваев с1авв всаск * р2 = пеы влас)с; /* р2 указывает на объект класса всаск, размещенный в куче */ в1.рпвн('П'); /* прямое обращение к объекту */ р1->раап('в'); /* обращение к объекту по указателю */ Из этого примера видны несколько ключевых проектных решений: (з по аналогии с 5!шп!а язык С зу(г!) С1авзез позволяет задать типы, из которых создаются переменные (объекты), тогда как, скажем, Мо(!п!а описывает молуль как набор объектов и функций.
В С зв(11) С!аваев класс — это тип (см. раздел 2.9), что стало главной особенностью С++. Но если слово с1авв опрелеляет в С++ пользовательский тип, то почему я не назвал его суре? В основном потому, что я не люблю изобретать новую терминологию, а соглашения, принятые в Б!шп!а, меня в большинстве случаев устраивали; и прелставление объектов пользовательского типа — часть объявления класса, что имеет далеко идущие последствия (см.
разделы 2А и 2.5). Например, это означает следующее: настоящие локальные переменные пользовательского типа можно реализовать без использования кучи (ее еще называют динамической памятью) и сборки мусора. Отсюда также следует, что при изменении прелставления объекта все функции, использующие его напрямую (не через указатель), должны быть перекомпилированы. (См. раздел 13.2, где описаны средства С++ для определения интерфейсов, позволяющие избежать такой перекомпиляции.); ш контроль доступа используется еще на стадии компиляции для ограничения доступа к элементам представления класса.
По умолчанию имена членов класса могут встречаться только в функциях, упомянутых в объявлении класса (см. раздел 2.10). Члены (обычно функции-члены), описанные в открытом интерфейсе класса — части, следующей за меткой рпЬ11с:,— могут использоваться и в других местах программы; ш для функций-членов указывается полный тип (включая тип возвращаемого значения и типы формальных аргументов). На основе данной спецификации производится статическая (во время компиляции) проверка типов (см. раздел 2.6). В то время это было отличием от С, где типы формальных аргументов не задавались в интерфейсе н не проверялись при вызове; ш определения функций обычно выносятся в другое место, чтобы класс больше походил на спецификацию интерфейса, чем на лексический механизм организации исходного кода. Это облегчает раздельную компиляцию функций-членов класса и внешней программы, которая их использует.
Поэтому техники компоновки, традиционной для С, достаточно для поддержки С++ (см. раздел 2.5); З функция нем ( ) является конструктором, для компилятора она имеет специальный смысл. Такие функции дают определенные гарантии относительно классов (см.
разлел 2.11): конструктор — в то время он назывался пемфункцией — обязательно будет вызван для инициализации каждого объекта своего класса перед его первым использованием; НИИИИИШ Эффективность исполнения а имеются указательные и неуказательные типы (они есть и в С, и в 81шц!а). Указатели могут указывать на объекты как встроенных, так и пользовательских типов; о как п в С, память для объектов может выделяться тремя способами: в стеке (автоматическая память), по фиксированному адресу (статическая память) и из кучи (динамическая память). Но в отличие от С, в С ъчгЬ С!аззез есть специальные операторы пем и йе1есе для выделения и освобождения динамической памяти (см.
раздел 2.11.2). 2.4. Эффективность исполнения В Яшц1а не может быть локальных или глобальных переменных типа класса, память для каждого объекта класса выделяется динамически оператором пеи. Измерения с помощью кембриджского симулятора убедили меня, что это основная причина неэффективности языка. Позднее Карел Бабчиски (Кате! ВаЬс(зйу) из Норвежского Вычислительного Центра представил данные о производительности 81шц1а, подтвердившие мой вывод [ВаЬс1зйу, 1984].
Уже по этой причине я хотел иметь глобальные и локальные переменные типа класса. Кроме того, наличие разных правил для создания и области действия переменных встроенных и пользовательских типов просто неизящно, а в некоторых случаях я видел, как страдает мой стиль программирования от отсутствия в 81шц1а локальных и глобальных переменных типа класса. Не хватало и возможности иметь указатели на встроенные типы в 81шц1а. Эти наблюдения со временем превратились в определенное правило дизайна С++: пользовательские и встроенные типы должны вести себя одинаково по отношению к правилам языка. И сам язык, и инструментальные средства должны обеспечивать для них одинаковую поддержку.