Программирование >>  Полиморфизм без виртуальных функций в с++ 

1 ... 5 6 7 [ 8 ] 9 10 11 ... 144


Рождение С with Classes

а преобладающей модели ее поддержки нет. Поэтому в случаях, когда параллельность нужна, ее следует реализовывать в библиотеках или в специализированном расширении так, чтобы одна конкретная форма не запрещала использование других.

Таким образом, на языке предлагались общие механизмы организации программ, а вовсе не поддержка конкретных предметных областей. Именно это и сделало С with Classes, позднее и С++, универсальным языком программирования, а не расширением С для специализированных приложений. Позже вопрос о выборе между поддержкой специализированных приложений и общи.м механизмом абстракций вставал неоднократно. И всякий раз принималось решение в пользу усовершенствования механизма абстракций. Поэтому в С++ нет ни встроенных типов для комплексных чисел, строк и матриц, ни прямой поддержки параллельности, устойчивости объектов, ни распределенных вычислений, ни сопоставле1шя образцов и манипуляций на уровне файловой системы. Я упомянул лишь малую толику часто предлагавшихся расширений. Но существуют библиотеки, поддерживающие все эти возможности.

Предварительное описание С with Classes было опубликовано в виде технического отчета в Bell Labs в апреле 1980 г. [Stroustrup, 1980] и в журнале SIGPLAN Notices [Stroustrup,1982]. Более подробный технический отчет Adding Classes to the С Language: An Exercise in Language Evolution [Stroustrup, 1980] напечатан в журнале Software: Practices and Experience. В данных работах заложена хорошая идея: описывать только те возможности, которые полностью реализованы и нашли применение. Такой подход соответствовал традициям Центра исследований по вычислительной технике компании Bell Laboratories. Я отошел от подобной тактики только тогда, когда назрела необходимость большей открытости относительно будущего С++, чтобы в свободной дискуссии по поводу эволюции языка могли принять участие многочисленные пользователи, которые не работали в AT&T.

С with Classes специально проектировался для обеспечения лучшей организации программ. Было решено, что с собственно вычислительной частью С и так справляется. Я считал принципиальным такой аспект: улучшение структуры не может достигаться за счет падения производительности по сравнению с С. Язык С with Classes не должен был уступать С во времени выполнения, компактности кода и данных. Однажды кто-то продемонстрировал систематическое трехпроцентное падение производительности новой версии по сравнению с С, вызванное наличием временных переменных, которые препроцессор С with Classes использовал в механизме возврата из функции. Недочет был признан неприемлемым, и причину быстро устранили. Аналогично, чтобы обеспечить совместимость формата хранения с С и, следовательно, избежать накладных расходов по памяти, в объекты классов не помещались никакие служебные данные.

Другой важной целью работы было стремление избежать ограничений на области использования С with Classes. Идеал (кстати, достигнутый) - С with Classes может применяться везде, где использовался С. Отсюда следовало, что новая версия ни в коем случае не должна была уступать С в эффективности, но эта эффективность не могла достигаться за счет отказа от некоторых, пусть даже уродливых особенностей С. Это соображение (если хотите, принцип) приходилось снова



и снова повторять тем людям (как правило, не работавшим постоянно с С with Classes), которые хотели сделать версию безопаснее, введя статический контроль типов а-ля Pascal. Альтернативу такой безопасности - вставку проверок в исполняемый код - решили реализовывать в отладочных средах. В самом языке-нельзя было организовывать таких проверок, ибо тогда он безнадежно проиграл бы С по скорости и расходу памяти. Поэтому такого рода контроль в С with Classes включен не был, хотя в некоторых средах разработки для С++ он имеется, но только в отладочном режиме. Кроме того, пользователи могут сами производить проверки во время выполнения там, где сочтут целесообразным (см. раздел 16.10 и [2nd]).

С поддерживает низкоуровневые операции, например манипуляции с битами и выбор между разными размерами целых. Имеются в нем и такие средства (допустим, явное преобразование типов), которые позволяют намеретю обойти систему контроля типов. С With Classes, а затем и С++ сохранили низкоуровневые и небезопасные особенности С. Но в С++ систематически устраняется необходимость использования таких средств за исключением тех мест, где без них никак не обойтись. При этом небезопасные операции выполняются только по явному указанию программиста. Я искренне убежден, что не существует единственно правильного способа написать программу, и дизайнер языка не должен заставлять программиста следовать определенному стилю. С другой стороны, дизайнер обязан всячески поддерживать все разнообразие стилей и способов программирования, доказавших свою эффективность, а равно предоставить такие языковые возможности и инструментальные средства, которые уберегли бы программиста от хорошо известных ловушек.

2.2. Обзор языковых возможностей

Вот сводка тех средств, которые были включены в первую версию 1980 г.:

□ классы (раздел 2.3);

□ производные классы (1ю пока без виртуальных функций, раздел 2.9);

□ контроль доступа - открытый/закрытый (раздел 2.10);

□ конструкторы и деструкторы (раздел 2.11.1);

□ функции, вызываемые при вызове и возврате (позже исключены, раздел 2.11.3);

□ дружественные (friend) классы (раздел 2.10);

□ контроль и преобразование типов аргументов функции (раздел 2.6).

В 1981 г. добавлены:

□ встраиваемые (inline) функции (раздел 2.4.1);

□ аргументы по умолчанию (раздел 2.12.2);

□ перегрузка оператора присваивания (раздел 2.12.1).

Поскольку С with Classes был реализован с помощью препроцессора, описывать следовало лишь новые, отсутствовавшие в С возможности, а вся мощь С и так оставалась в распоряжении пользователей. В то время оба эти аспекта были должным образом оценены. Раз С - подмножество языка, то объем работы по поддержке и документированию намного уменьшается. Это особен1ю важно, поскольку на



Я сохранил оригинальный синтаксис и стиль С with Classes. Отличия от С++ и современного стиля кодирования вряд ли у кого-то вызовут затруднения, а некоторым читателям будут интересны. Однако очевидные ляпы исправлены. Также добавлены комментарии, которых в исходном тексте не было.

протяжении нескольких лет мне приходилось заниматься документированием и поддержкой С with Classes и С++ одновременно с экспериментированием, проектированием и реализацией новых версий. Доступность всех возможностей С гарантировала, что по недосмотру или из-за моих предрассудков не будет введено никаких ограничений, которые лишат пользователей привычных средств. Естественно, переносимость на машины, где С уже имелся, обеспечивалась автоматически. Изначально С with Classes был реализован и эксплуатировался на DEC PDP/11, но вскоре был перенесен на DEC VAX и компьютеры на базе процессора Motorola 68000.

С with Classes все еще рассматривался как диалект С, а не как самостоятельный язык. Даже классы тогда назывались абстрактными типами да1шых (abstract data type facility) [Stroustrup, 1980]. Поддержка объектно-ориентированного профам.мирования была провозглашена лишь после добавления в С++ виртуальных функций [Stroustrup, 1984].

2.3. Классы

Очевидно, самой важной чертой С with Classes, а позже и С++ была концепция класса. Многие ее аспекты видны из следующего примера [Stroustrup, 1980]:

class stack {

char s[SIZE]; /* массив символов */

char* min; /* указатель на конец стека */

char* top; /* указатель на вершину стека */

char* max; /* указатель на начало выделенной области */

void new(); /* функция инициализации (конструктор) */ public:

void push(char);

char pop();

Класс - это определенный пользователем тип данных. Он содержит описания типов членов класса, то есть представление переменной данного типа (объекта класса), и набор операций (функций) для манипулирования такими объектами. Класс также определяет права доступа к своим члена.м со стороны пользователей. Функции-члены обычно определяются отдельно:

char stack.pop О {

if (top <= min) error( стек пуст ); return *(--top);

Теперь можно определить и использовать объекты класса stack:

class stack si, s2; /* две переменные типа stack */

class stack * pi = &s2; /* pi указывает на s2 */



1 ... 5 6 7 [ 8 ] 9 10 11 ... 144

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика