системе UNIX. Средства обработки особых ситуаций и параллельного
программирования, требующие нетривиальной загрузки и поддержки в
процессе выполнения, не были включены в C++. Вследствие этого
реализация C++ очень легко переносима. Однако есть полные основания
использовать C++ в среде, где имеется гораздо более существенная
поддержка. Такие средства, как динамическая загрузка, пошаговая
трансляция и база данных определений типов могут с пользой
применяться без воздействия на язык.
Типы и средства скрытия данных в C++ опираются на проводимый во
время компиляции анализ программ с целью предотвращения случайного
искажения данных. Они не обеспечивают секретности или защиты от
умышленного нарушения правил. Однако эти средства можно
использовать без ограничений, что не приводит к дополнительным
расходам времени на выполнение или пространства памяти.
Исторические замечания
Безусловно, C++ восходит главным образом к C [7]. C сохранено как
подможество, поэтому сделанного в C акцента на средствах низкого
уровня достаточно, чтобы справляться с самыми насущными задачами
системного программирования. C, в свою очередь, многим обязано
своему предшественнику BCPL [9]; на самом деле, комментарии //
(заново) введены в C++ из BCPL. Если вы знаете BCPL, то вы
заметите, что в C++ по-прежнему нет VALOF блока. Еще одним
источником вдохновения послужил язык Simula67 [2,3]; из него была
позаимствована концепция класса (вместе с производными классами и
функциями членами). Это было сделано, чтобы способствовать
модульности через использование виртуальных функций. Возможности
C++ по перегрузке операций и свобода в расположении описаний везде,
где может встречаться оператор, похожи на Алгол68 [14].
Название C++ - изобретение совсем недавнее (лета 1983его). Более
ранние версии языка использовались начиная с 1980ого и были
известны как "C с Классами". Первоначально язык был придуман
потому, что автор хотел написать модели, управляемые прерываниями,
для чего был бы идеален Simula67, если не принимать во внимание
эффективность. "C с Классами" использовался для крупных проектов
моделирования, в которых строго тестировались возможности
написания программ, требующих минимального (только) пространства
памяти и времени на выполнение. В "C с Классами" не хватало
перегрузки операций, ссылок, виртуальных функций и многих деталей.
C++ был впервые введен за пределами исследовательской группы автора
- стр 13 -
в июле 1983его; однако тогда многие особенности C++ были еще не
придуманы.
Название C++ выдумал Рик Масситти. Название указывает на
эволюционную природу перехода к нему от C. "++" - это операция
приращения в C. Чуть более короткое имя C+ является синтаксической
ошибкой; кроме того, оно уже было использовано как совсем другого
языка. Знатоки семантики C находят, что C++ хуже, чем ++C. Названия
D язык не получил, поскольку он является расширением C и в нем не
делается попыток исцеляться от проблем путем выбрасывания
различных особенностей. Еще одну интерпретацию названия C++ можно
найти в приложении к Оруэллу [8].
Изначально C++ был разработан, чтобы автору и его друзьям не
приходилось программировать на ассемблере, C или других современных
языках высокого уровня. Основным его предназначением было сделать
написание хороших программ более простым и приятным для отдельного
программиста. Плана разработки C++ на бумаге никогда не было;
проект, документация и реализация двигались одновременно.
Разумется, внешний интерфейс C++ был написан на C++. Никогда не
существовало "Проекта C++" и "Комитета по разработке C++". Поэтому
C++ развивался и продолжает развиваться во всех направлениях чтобы
справляться со сложностями, с которыми сталкиваются пользователи, а
также в процессе дискуссий автора с его друзьями и коллегами.
В качестве базового языка для C++ был выбран C, потому что он (1)
многоцелевой, лаконичный и относительно низкого уровня; (2)
отвечает большинству задач системного программирования; (3) идет
везде и на всем; и (4) пригоден в среде программирования UNIX. В C
есть свои сложности, но в наспех спроектированном языке тоже были
бы свои, а сложности C нам известны. Самое главное, работа с C
позволила "C с Классами" быть полезным (правда, неудобным)
инструментом в ходе первых месяцев раздумий о добавлении к C
Simula-образных классов.
C++ стал использоваться шире, и по мере того, как возможности,
предоставляемые им помимо возможностей C, становились все более
существенными, вновь и вновь поднимался вопрос о том, сохранять ли
совместимость с C. Ясно, что отказавшись от определенной части
наследия C можно было бы избежать ряда проблем (см., например,
Сэти [12]). Это не было сделано, потому что (1) есть миллионы строк
на C, которые могли бы принести пользу в C++ при условии, что их не
нужно было бы полностью переписывать с C на C++; (2) есть сотни
тысяч строк библиотечных функций и сервисных программ, написанных
на C, которые можно было бы использовать из или на C++ при условии,
что C++ полностью совместим с C по загрузке и синтаксически очень
похож на C; (3) есть десятки тысяч программистов, которые знают C,
и которым, поэтому, нужно только научиться использовать новые
особенности C++, а не заново изучать его основы; и (4), поскольку
C++ и C будут использоваться на одних и тех же системах одними и
теми же людьми, отличия должны быть либо очень большими, либо очень
маленькими, чтобы свести к минимуму ошибки и недоразумения. Позднее
была проведена проверка определения C++, чтобы удостовериться в
том, что любая конструкциия, допустимая и в C и в C++,
действительно означает в обоих языках одно и то же.
Язык C сам эволюционировал за последние несколько лет, частично
под влиянием развития C++ (см. Ростлер [11]). Предварительный
грубый ANSI стандарт C [10] содержит синтаксис описаний функций,
заимствованный из "C с Классами". Заимствование идей идет в обе
стороны; например, указатель void* был придуман для ANSI C и
- стр 14 -
впервые реализован в C++. Когда ANSI стандарт разовьется несколько
дальше, придет время пересмотреть C++, чтобы удалить необоснованную
несовместимость. Будет, например, модернизирован препроцессор
(#с.11), и нужно будет, вероятно, отрегулировать правила
осуществления плавающей арифметики. Это не должно оказаться
болезненным, и C и ANSI C очень близки к тому, чтобы стать
подмножествами C++ (см. #с.11).
Эффективность и структура
C++ был развит из языка программирования C и за очень немногими
исключениями сохраняет C как подмножество. Базовый язык, C
подмножество C++, спроектирован так, что имеется очень близкое
соответствие между его типами, операциями и операторами и
компьютерными объектами, с которыми непосредственно приходится
иметь дело: числами, символами и адресами. За исключением операций
свободной памяти new и delete, отдельные выражения и операторы C++
обычно не нуждаются в скрытой поддержке во время выполнения или
подпрограммах.
В C++ используются те же последовательности вызова и возврата из
функций, что и в C. В тех случаях, когда даже этот довольно
эффективный механизм является слишком дорогим, C++ функция может
быть подставлена inline, удовлетворяя, таким образом, соглашению о
записи функций без дополнительных расходов времени выполнения.
Одним из первоначальных предназначений C было применение его
вместо программирования на ассемблере в самых насущных задачах
системного программирования. Когда проектировался C++, были приняты
меры, чтобы не ставить под угрозу успехи в этой области. Различие
между C и C++ состоит в первую очередь в степени внимания,
уделяемого типам и структурам. C выразителен и снисходителен. C++
еще более выразителен, но чтобы достичь этой выразительности,
программист должен уделить больше внимания типам объектов. Когда
известны типы объектов, компилятор может правильно обрабатывать
выражения, тогда как в противном случае программисту пришлось бы
задавать действия с мучительными подробностями. Знание типов
объектов также позволяет компилятору обнаруживать ошибки, которые в
противном случае остались бы до тестирования. Заметьте, что
использование системы типов для того, чтобы получить проверку
параметров функций, защитить данные от случайного искажения, задать
новые операции и т.д., само по себе не увеличивает расходов по
времени выполнения и памяти.
Особое внимание, уделенное при разработке C++ структуре,
отразилось на возрастании масштаба программ, написанных со времени
разработки C. Маленькую программу (меньше 1000 строк) вы можете
заставить работать с помощью грубой силы, даже нарушая все правила
хорошего стиля. Для программ больших размеров это не совсем так.
Если программа в 10 000 строк имеет плохую структуру, то вы
обнаружите, что новые ошибки появляются так же быстро, как
удаляются старые. C++ был разработан так, чтобы дать возможность
разумным образом структурировать большие программы таким образом,
чтобы для одного человека не было непомерным справляться с
программами в 25 000 строк. Существуют программы гораздо больших
размеров, однако те, которые работают, в целом, как оказывается,
состоят из большого числа почти независимых частей, каждая из
которых намного ниже указанных пределов. Естественно, сложность
- стр 15 -
написания и поддержки программы зависит от сложности разработки, а
не просто от числа строк текста программы, так что точные цифры, с
помощью которых были выражены предыдущие соображения, не следует
воспринимать слишком серьезно.
Не каждая часть программы, однако, может быть хорошо