Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
41
Добавлен:
16.04.2013
Размер:
151.55 Кб
Скачать

Форма подтипов

Абстрактные типы данных успешны постольку, поскольку они ведут себя так же, как и собственные типы. Собственные типы, например целые типы в С, выступают в качестве иерархии подтипов. Это полезная модель для открыто наследуемых иерархий типов, она повышает легкость использования иерархий на основе полиморфизма. Вот рецепт для построения такой иерархии типов. Базовый класс делается абстрактным. Он используется для наследования интерфейса. Производные классы будут конкретизировать и реализовывать этот интерфейс.

class Abstract_Base {

public:

//Интерфейс – “совсем виртуальный”

Abstract_Base(); //конструктор по умолчанию

Abstract_Base( const Abstract_Base&); //копирующий

//конструктор

virtual - Abstract_Base() = 0; //чисто виртуальный

……………

protected:

//используется вместо privat из-за наследования

……………

privat:

//часто остается пустым – иначе будет

//мешать будующим разработкам

……………

};

class Derived: virtual public Abstract_Base {

public:

//конкретный экземпляр

Derived(); //конструктор по умолчанию

Derived(const Derived&); //копирующий конструктор

-Derived()ж //деструктор

Derived& operator=(const Derived&); //прсваивание

……………

protected:

//используется вместо privat если ожидается наследование

……………

private:

//используется для деталей реализации

……………

};

Как правило, корень иерархии оставляют абстрактным. Это делает разработку более гибкой. Обычно на этом этапе никакая конкретная реализация не создается. Наличие чисто виртуальных функций запрещает объявления объектов соответствующего типа. Заметьте, что Abstract_Base() – чисто виртуальная функция.

Этот уровень проекта фокусируется на открытом интерфейсе, которым является операции, ожидаемые от любого из подтипов иерархии. Вообще, основные конструкторы, как правило, должны присутствовать, и они могут не быть виртуальными. Кроме того, большинство полезных агрегатов нуждаются в явном определении присваивания, которое отличается от семантики присваивания, принятой по умолчанию. Деструктор является виртуальным, поскольку он задействуется на этапе выполнения и его поведение зависит от размера объекта, который может отличаться от типа к типу иерархии. Наконец, виртуальное открытое наследование (virtual public) позволяет быть уверенным в том, что при множественном наследовании мы не получим много копий абстрактного класса.

Идентификация типа на этапе выполнения

Идентификация типа на этапе выполнения (run-time type identification, RTTI) предоставляет механизм для безопасного выявления типа, на который направлен во время работы программы указатель базового класса. Этот механизм включает dynamic_cast – оператор над указателем на базовый класс, typtid – оператор для выяснения типа объекта и type_info – структуру, которая на этапе выполнения предоставляет информацию о соседствующем типе.

Оператор dynamic_cast имеет следующий вид:

dynamic_cast <тип> ( V )

Где тип должен быть указателем или ссылкой на тип класса, а должна быть значением подхода указателя или ссылки. Это приведение используется с классами, имеющими виртуальные функции. Вот как оно применяется:

class Base { virtual void foo(); …………… };

class Derived : public Base { …………… };

void fcn(Base* ptr)

{

Derived* dptr = dynamic_cast<Derived*>(prt);

……………

}

В этом примере приведение преобразует значение указателя prt к типу Derived*. Если преобразование неприменимо, возвращается нулевой указатель NULL Это называется понижающим приведением (down cast). Динамические приведения также работают с типами-ссылками.

Оператор typied() может быть применен к имени типа или выражению для выяснения истинного типа аргумента. Этот оператор возвращает ссылку на класс type_info, который предоставляется системой и определен в заголовочном файле type_info.h (в некоторых компиляторах typeinfo.h). Класс type_info предоставляет функцию-член name(), которая возвращает строку, являющуюся именем типа. Кроме того, он предлагает перегруженные операторы проверки на равенство. Не забудьте изучить свою реализацию для выяснения деталей интерфейса этого класса.

Соседние файлы в папке Тельминов (мб)