Страница 18 из 25 Полиморфные классы Полиморфные классы определяются тем же образом,а что и полиморфные функции. Например: class set : public common { class set_mem { set_mem *next; object *mem; set_mem(common *m, set_mem *n) { mem = m; next = n;} } *tail; public: int insert(common *); int remove(common *); int member(common *); set() { tail = 0; } - set() { if (tail) error("непустое множество"); } } Таким образом, класс s e t (для реализации множества) реализован как связанный список объектов s e t _ m e m , каждый из которых указывает на класс c o m m o n . Указатели на объекты (не сами объекты) введены в класс. Для полноты описания класс s e t сам является производным c o m m o n , таким образом, можно создать множество множеств. Так как класс s e t реализован независимо от данных составляющих его объектов, объект может быть членом двух и более множеств. Такая модель являетсяа очень общей и может быть использованаа( и в действительности использовалась) для создания "абстракций" типа множество, вектор, связанный список, таблица. Наиболее отличительная черта данной модели для "классов-контейнеров" состоитв том, что, в общем случае, ни контейнер не зависит от данных, содержащихся в объектах, ни сами объекты независят от данных, идентифицирующих их контейнер (контейнеры). Это часто является важным структурным преимуществом : классы могут проектироваться и использоваться без забот о том, структуры данных какого типа необходимы для программы, их использующей. Наиболее очевидный недостаток состоитв том, что издержки составляют как минимум один указатель на член класса (два указателя в рамках вышеприведенного класса s e t для реализации связанного спискай (*1). Другое преимущество состоитв том,а что такие классы-контейнеры могут быть способны содержать гетерогенный набор членов (*2). Если это нежелательно, можно тривиальныма образом определить производный класс, который допускает в качестве членов только один конкретный класс. Например: class apple_set: public set { public: int insert(apple *a) { return set::insert(a); } int remove(apple *a) { return set::remove(a); } int member(apple *a) { return set::member(a); } }; __________ (*1) Плюс еще один указатель для реализации механизма виртуальных функций. См.ниже секцию 21. "Эффективность". (*2) То есть, разных классов. - прим.переводчика. Заметим,а что, так как функции класса a p p l e _ s e t не выполняют никаких действий в дополнение к тем, что выполняют функции базового класса s e t , они будут полностью (то есть до полного отсутствия каких бы то ни было издержек) оптимизированы. Они служат только для того, чтобы обеспечить контроль типов во время компиляции. Класс c o m m o n подходящим набором полиморфных классов и функций находится в стадии разработки. Предполагается, что он будет входить в состав стандартной библиотеки. |