|
Программирование >> Полиморфизм без виртуальных функций в с++
Язык Simula и распределенные системы важнее всего и помогало мне больше, чем примитивные сильно типизированные языки, с которыми доводилось работать раньше. Так я пришел к уже звучавшему выше выводу, что систе.ма типов в языке Pascal не просто бесполезна - это смирительная рубашка, которая создает больше проблем, нежели решает, заставляя .меня жертвовать чистотой дизайна ради удовлетворения причуд компилятора. Обнаруженный контраст между строгостью Pascal и гибкостью Simula оказался чрезвычайно важен при разработке С++. Концепция классов в Simula представлялась мне ключевым фактором, и с той поры я считаю, что при проектировании программ следует сосредотачивать свое внимание именно на классах. Я работал с Simula и прежде (во вре.мя учебы в университете города Аархус в Дании), но был приятно удивлен следующим: че.м больше программа, тем очевидней польза от возможностей Simula. Механиз.мы классов и сопрогра.мм, а также исчерпывающий контроль типов гарантировали, что число ошибок увеличивается с ростом програм.мы не более чем линейно (что было неожиданно). Напротив, программа работала, скорее, как набор очень маленьких профаммок, нежели как большой монолит, и поэтому писать, пони.мать и отлаживать ее было проще. Однако реализация самого языка Simula не масштабировалась в той же степени, что и моя программа. В результате весь проект чуть не закончился крахом. В то время я пришел к выводу, что реализация Simula (в отличие от самого языка) была ориентирована на небольшие по объему программы, а для больщих не приспособлена [Stroustrup, 1979]. На связывание отдельно скомпилированных классов уходила масса времени: на компиляцию 1/30 части программы и связыва1ше ее с остальными, уже откомпилированны.ми модуля.ми тратилось больше времени, чем па компиляцию и связывание всей программы как монолита. Думаю, что, вероятнее всего, это была пробле.ма используемого ко.мпоновщика, а не самого языка Simula, но это слабое утешение. Кроме того, производительность программы была такой низкой, что не оставляла надежд получить от симулятора хоть сколько-нибудь полезные данные. Плохие показатели производительности были обусловлены языком и его реализацией, а не прилол.енисм. Проблема накладных расходов является в Simula фундаментальной и неустранимой. Она коренится в некоторых особенностях языка и их взаимодействиях: проверке типов во время исполнения, гарантированной инициализации переменных, поддержке параллельности, сборке мусора для объектов, созданных пользователем, и записей активации процедур. Измерения показали: более 80% времени тратится на сборку мусора, хотя управление ресурсами брала на себя моделируемая система, так что мусор вообще не появлялся. Современные реализации Simula (15 лет спустя) стали лучше, но, по моим сведениям, увеличения производительности на порядок так и не достигнуто. Чтобы не бросать проект, я переписал симулятор на BCPL и запускал его на экспериментальном компьютере САР. Опыт кодирования и отладки на BCPL [Richards, 1980] оставил у меня неприятные воспоминания. Язык С по сравнению с BCPL - язык очень высокого уровня. Ни контроля типов, ни поддержки во время исполнения в BCPL здесь нет и в помине. Однако получившийся симулятор работал достаточно быстро и с его помощью я получил целый ряд полезных результатов. Они прояснили многие вопросы и легли в основу нескольких статей по операцио1шым система.м [Stroustrup, 1978, 1979b, 1981]. Предыстория С++ Расставшись с Кембриджем, я поклялся себе никогда больше не приступать к решению задачи, располагая такими неподходящими инструментами, как те, с которыми я намучился при проектировании и реализации симулятора. Для истории С++ важную роль сыграло составленное мной представление о подходящем инструменте для проектов такого масштаба, как большой симулятор, операционная система и аналогичные задачи системного программирования. Вот эти критерии: □ хороший инструмент должен предоставлять средства организации программ, подобные имеющимся в Simula: классы, форму их иерархии, поддержку параллельности и сильный (т.е. статический) контроль типов, основанный на классах. Эти критерии представлялись мне тогда (да и теперь) существенными для поддержки процесса проектирования, а не для реализации программы; □ необходимо, чтобы он генерировал программы, работающие так же быстро, как написанные на BCPL, и обладал способностью BCPL объединять раздельно откомпилированные модули в единую программу. Должно быть простое соглашение о связях, чтобы удалось объединять модули, написанные на разных языках, таких как С, Algol68, Fortran, BCPL, ассемблер и т.д. Иначе программист будет вынужден бороться с ограничениями, присущими какому-то одному языку; □ инструмент должен обеспечивать переносимую реализацию. Мой опыт показал, что правильная реализация, остро необходимая мне сейчас, будет готова не раньше следующего года , да и то на компьютере, которого у меня нет. Отсюда следует, что должно быть несколько источников реализации инструмента (никакой монополист не сможет поддерживать всех пользователей редких машин, а также бедных студентов). Не должно быть также сложной системы поддержки времени исполнения, которую трудно переносить, и допустима лишь очень ограниченная зависимость инструмента от операционной системы. Эти критерии еще не были четко сформулированы, когда я покидал Кембридж. Некоторые из них окончательно оформились лишь в ходе последующего осмысления собственного опыта, приобретенного при создании симулятора и программ, которые я писал в течение еще пары лет, а также опыта других людей. С++ в том виде, какой он принял к моменту выхода версии 2.0, полностью отвечает данным критериям; серьезные проблемы, с которыми я столкнулся при проектировании шаблонов и обработке исключений, связаны с отходом от некоторых из этих принципов. Я полагаю, что самой важной особенностью сформулированных выше правил является их слабая связь с нюансами конкретных языков программирования. Вместо этого они налагают определенные ограничения на решение. Когда я работал в Кембридже, лабораторию вычислительной техники возглавлял Морис Уилкс (Maurice Wilkes). Помощь во всех технических вопросах мне оказывали мой руководитель Дэвид Уилер (David Wheeler) и Роджер Нидэм (Roger Needham). Мои знания в области операционных систем и интерес к модульности и межмодульным коммуникациям способствовали развитию С++. Язык С и системное программирование Например, модель защиты в С++ базируется на концепции предоставления и передачи прав доступа; различие между инициализацией и присваиванием возникло благодаря размышлениям о способности переноса (transferring capabilities); концепция const берет начало от механизмов защиты от чтения/записи в аппаратных устройствах; механизм обработки исключений появился в связи с работой над отказоустойчивыми системами, выполненной группой под руководством Брайана Рэнделла (Brian Randell) в Ньюкасле в 70-х гг. 1.2. Язык С и системное программирование На языке С я начал работать в Лондоне в 1975 г. и оценил его преимущества по сравнению с другими языками, которые принято называть языками для системного программирования, машинно-ориентирова1шыми или низкоуровневыми. Из таких языков мне были известны PL 360, Coral, Mary и другие, но в основном BCPL. Я не только пользовался BCPL, но однажды и реализовал его путем трансляции в промежуточный микрокод - 0-код, так что хорошо представлял себе низкоуровневые аспекты, связанные с эффективностью языков такого класса. Защитив диссертацию в Кембридже и получив работу в Bell Labs, я еще раз иззгчил С по книге Кернигана [Kernighan, 1978]. В то время я не был экспертом по С и рассматривал его в основном как самый современный и известный пример языка системного программирования. Лишь позже, приобретая собственный опыт и беседуя с коллегами - Стью Фельдманом (Stu Feldman), Стивом Джонсоном (Steve Johnson), Брайаном Керниганом и Деннисом Ричи, - я начал по-настоящему понимать С. Таким образом, общее представление о языках системного программирования значило для формирования С++ по меньшей мере столько же, сколько конкретные технические детали С. Я довольно хорошо знал Algol68 [Woodward,1974] по работе над небольшими проектами в Кембридже и видел связь между конструкциями этого языка и С. Иногда мне казалось полезным рассматривать конструкции С как частные случаи более общих конструкций Algol68. Любопытно, что я никогда не рассматривал Algol68 в качестве языка системного программирования (несмотря на то что сам пользовался написанной на нем операционной системой). Подозреваю, причина здесь в том, что я считал очень важными переносимость, простоту связывания с программами на других языках и эффективность исполнения. Как-то раз я сказал, что Algol68 с классами, как в Simula, - это язык моей мечты. Однако в качестве практического инструмента С казался мне лзгчше, чем Algol68. 1.3. Немного об авторе книги Говорят, что структ)фа системы отражает структ)фу организации, в которой она была создана. В общем и целом я поддерживаю это мнение. Из него также следует, что если система есть плод работы одного человека, то она отражает склад его личности. Оглядываясь назад, я думаю, что на общую структуру С++ мое мировоззрение наложило такой же отпечаток, как и научные концепции, лежащие в основе отдельных его частей.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |