|
Программирование >> Полиморфизм без виртуальных функций в с++
□ наличие множества конфликтующих друг с другом определений делает неудобным и небезопасным любой тип Boolean; □ многие пользователи хотят иметь возможность перегружать функции на базе типа Boolean. К моему удивлению, комитет ANSI/ISO принял эти аргументы, поэтому bool теперь входит в С++ как отдельный интегральный тип и имеет литералы true и false. Ненулевые значения можно неявно преобразовать в true, а true неявно преобразуется в 1. Нуль можно неявно преобразовать в false, а false неявно преобразуется в 0. За счет этого обеспечивается высокая степень совместимости. Глава 12. Множественное наследование Потому что у тебя есть отец и мать. сотр.1апд.с++ 12.1. Введение Множественное наследование - возможность иметь более одного прямого базового класса - зачастую считалось са.мой важной особенностью версии 2.0. В то время я не соглашался с этим, так как полагал, что совокупность улучшений системы типов гораздо важнее. Кроме того, не стоило включать в версию 2.0 множественное наследование. Оно действительно необходимо в С++, но гораздо менее важно, чем параметризованные типы, а для некоторых даже параметризованные типы - нестояшая мелочь по сравнению с обработкой исключений. Но получилось так, что параметризованные типы появились только в версии 3.0, а исключения - еще позже. Лично мне параметризованных типов не хватало гораздо больше, чем множественного наследования. Работа над множественным наследованием проводилась именно в то время по ряду причин: оно хорошо согласуется с системой типов С++ без крупных расширений, а реализацию можно было осуществить в рамках Cfront. Следует учесть еще один фактор, абсолютно иррациональный: никто, по-видимому, не сомневался, что я смогу эффективно реализовать шаблоны. А вот множественное наследование, по общему мнению, с трудом поддавалось эффективной реализации. Например, рассуждая о С++, Брэд Кокс (Brad Сох) в своей книге, посвященной Objective С, заявил, что добавить множественное наследование в С++ невозможно [Сох, 1986]. Таким образом, мне был брошен вызов. Я не смог его не принять, потому что думал о множественном наследовании еще в 1982 г. (см. раздел 2.13), а в 1984 г. нашел для него простую и эффективную реализацию. Полагаю, что это единственный случай, когда на последовательность событий оказала влияние мода. В сентябре 1984 г. я представил механизм перегрузки операторов в С++ на конференции IFIP WG2.4 в Кентербери [Stroustrup, 1984b]. Там я встретил Стей-на Крогдала (Stein Krogdahl) из университета Осло; Стейн как раз заканчивал работу над предложением о включении множественного наследования в Simula [Krogdahl, 1984]. Его идеи легли в основу реализации обыкновенных множественных базовых классов в С++. Уже позже стало известно, что почти идентичное предложение для Simula уже рассматривалось ранее. Оле-Йохан Дал (Ole-Johan Dahl) рассматривал множественное наследование еще в 1966 г. и отверг его из-за неизбежного усложнения сборщика мусора в Simula [Dahl, 1988]. 12.2. Базовые классы Первая и самая важная причина для рассмотрения множественного наследования заключалась в следующем: необходимо было обеспечить такое объединение двух классов в один, при котором объекты результирующего класса ведут себя, как объекты любого из базовых классов [Stroustrup, 1986]: Довольно стандартный пример использования множественного наследования - создание двух библиотечных клоссов displayed и task для представления объектов, одновременно находящихся под управлением диспетчера вывода на экран и обладающих свойствами сопрограммы, работающей под управлением планировщика. Тогда программист мог бы создавать такие классы: class my displayed task : public displayed, public task { . . . class my task : public task { не наследует displayed . . . class iny displayed : public displayed { не наследует task ... Если использовать только одиночное наследование, то программисту доступны лишь два последних варианта . В то время меня беспокоило, что библиотечные классы становятся слишком громоздкими, поскольку должны удовлетворять как можно большему числу требований. Множественное наследование я рассматривал как потенциально важное средство организации библиотек с меньшим числом классов и зависимостей между ними. Пример с классами task и displayed показывает, как можно представить свойства параллельности и вывода на экран с помощью отдельных классов, не перекладывая работу на программиста. Неоднозначности разрешаются во время компиляции: class А { public: void f(); /* ... */ }; class В ( public: void f(); /* ... */ }; class С : public A, public В {/* f{) нет ... */ }; void g() { C* p; p->f(); ошибка: неоднозначность
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |