|
Программирование >> Полиморфизм без виртуальных функций в с++
Сам я написал первые версии Cfront (1.0, 1.1, 1.2) и сопровождал их. В течение нескольких месяцев перед выпуском версии 1.0 в 1985 г. со мной работал Стив Дьюхерст (Steve Dewhurst). Большую работу по написанию синтаксического анализатора для Cfront версий 1.0, 1.1, 2.1 и 3.0 проделала Лаура Иве (Laura Eaves). Я много сделал для версий 1.2 и 2.0, но, уже начиная с версии 1.2, достаточное время этой работе уделял Стэн Липпман (Stan Lippman). Большую часть работы над версиями 2.1 и 3.0 проделали Лаура Иве, Стэн Липпман, Джордж Логотетис (George Logothetis), Джуди Уорд (Judi Ward) и Нэнси Уилкинсон (Nancy Wilkinson). Работой над версиями 1.2, 2.0, 2.1 и 3.0 руководила Барбара My. Эндрю Кениг организовал тестирование версии 2.0. Сэм Харадхвала (Sam Haradhvala) из компании Object Design Inc. выполнил первую реализацию шаблонов в 1989 г., а Стэн Липпман расширил и улучшил ее для версии 3.0 в 1991 г. Первая реализация обработки исключений для Cfront выполнена компанией Hewlett-Packard в 1992 г. Помимо кода, вошедшего в основные версии Cfront, было создано и много локальных вариантов компилятора С++ на его базе. На протяжении нескольких лет такие компании, как Apple, Centerline (бывшая Saber), Comeau Computing, Glockenspiel, ParcPlace, Sun, Hewlett-Packard и другие поставляли продукты, содержащие модифицированные версии Cfront. 3.4. Возможности языка При переходе от С with Classes к С++ языку были добавлены следующие возможности: □ виртуальные функции (см. раздел 3.5); □ перегрузка функций и операторов (см. раздел 3.6); □ ссылки (см. раздел 3.7); □ константы (см. раздел 3.8); □ контроль над распределением свободной памяти со стороны пользователя (см. раздел 3.9); □ улучшенный контроль типов (см. раздел 3.10). Кро.ме того, из языка изъяли функции call и return (см. раздел 2.11), поскольку ими никто не пользовался, и внесли некоторые мелкие усовершенствования. 3.5. Виртуальные функции Самой яркой новой возможностью С++, оказавшей офомное влияние на стиль профаммирования, стали виртуальные функции. Идея была заимствована из Simula, но модифицирована с целью сделать реализацию проще и эффективнее. Логическое обоснование виртуальных функций изложено в работах [Stroustrup, 1986] и [Stroustrup, 1986Ь]. Для того чтобы подчеркнуть центральную роль виртуальных функций в профаммировании на С++, приведу развернутую цитату из [Stroustrup, 1986]: Абстрактный тип данных - это черный ящик . Коль скоро он определен, объемлющая программа уже не может вмещаться в его работу. Единственный способ адаптировать его к нуждам нового пользователя - изменить определение. Это может быть причиной недостаточной гибко-аи. Рассмотрим тип shape, предназначенный для систем роботы с графикой. Предпопожим, что система должна поддерживать окружности, треугольники и квадраты и имеются следующие классы: class point { /*...*/ }; class color { /*...*/ } ; Можно было бы определить класс shape таким образом: enum kind { circle, triangle, square } ,- class shape { point center; color col; kind k; представление геометрической фигуры public: point where 0 { return center; } void move(point to) { center = to; drawO; } void draw(); void rotate(int); другие операции Поле типа к необходимо операциям типа draw () и rotate () для адекватного определения фигуры (в Pascal-подобном языке можно было бы использовать вариантную запись с тэгом к). Тогда функция draw () определялась бы ток: void shape::draw() { switch (к) { case circle: нарисовать окружность break; case triangle: нарисовать треугольник break; case square: нарисовать квадрат break; Полная неразбериха! Функция вроде draw () должна знать обо всех типах фигур. Поэтому код такой функции растет при добавлении в систему каждой новой фигуры. Определив новую фигуру, необходимо просмотреть и, возможно, модифицировать весь ранее написанный код. Добавить новую фигуру не удастся, если исходный код недоступен. Поскольку добавление новой фигуры затрагивает все важные операции нод фигурами, от программиста требуется высокая квалификация, и все равно не исключено, что в старый код будут внесены ошибки. Выбор представления конкретных фигур может серьезно усложниться, если требуется, чтобы оно, ло крайней мере, частично соответствовало фиксированному образцу, принятому для обобщенного типа shape. проблема здесь в том, что между общими свойствами любой фигуры (она имеет цвет, может быть нарисована и т.д.) и свойствами конкретной фигуры (окружность - это фигура, которая имеет радиус, прорисовывается функцией вычерчивания окружности и т.д.) нет четкого разграничения. Возможность выразить такое разграничение и воспользоваться им составляет суть объектно-ориентированного программирования. Язык, обладающий такими выразительными возможностями, поддерживает объектно-ориентированное программирование. Остальные языки его не поддерживают. Механизм наследования в Simula предлагает рещение, которое я принял на вооружение в С++. Сначала мы описывоем класс, в котором определены общие свойства всех фигур: class shape { point center; color col; ... public: point where() { return center; } void move(point to) { center = to; drawO; } virtual void drawO; virtual void rotate(int); . . . Bee функции, для которых можно определить порядок вызова, но нельзя предоставить реализацию для фигуры общего вида, помечены словом virtual (общий для Simula и С++ термин, означающий может быть переопределена в классе, производном от данного ). Имея данное определение, для манипуляций с фигурами можно написать обобщенные функции: void rotate all(shape** v, int size, int angle) повернуть все элементы вектора v размера size на angle градусов for (int i = 0; i < size; i++) v[i]->rotate(angle); Чтобы определить конкретную фигуру, нужно сформулировать, чту это за фигура и задать ее специфические свойства, в том числе виртуальные функции. class circle : public shape { int radius; public: void drawO { /* ... */ }; void rotate(int) {} да, это пустая функция В С++ говорят, что класс circle является производным от shape, а класс shape - базовый для circle. В другой терминологии circle и shape называются соответственно подклассом и суперклассом . Дальнейшее обсуждение виртуальных функций и объектно-ориентированного программирования см. в разделах 13.2, 12.3.1, 13.7, 13.8 и 14.2.3. Насколько я помню, в то время виртуальные функции не вызвали большого интереса. Возможно, я недостаточно хорошо объяснил заложенные в них концепции, но преобладаюшей реакцией в кругу близких мне людей было безразличие и скептицизм. Обшее мнение сводилось к тому, что виртуальные функции - это
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |