Базовый класс координат. class Coord // базовый класс координат
class Coord // базовый класс координат
{
protected: // защищённые члены класса
double x , y ; // координаты
public: // открытые члены класса
Coord ( ) { x = 0 ; y = 0 ; } // конструктор базового класса
virtual ~Coord ( ) { cout<<"Delete x , y\n" ; } // виртуальный деструктор базового класса
} ;
Производный класс точки
class Dot : public Coord // наследник класса координат
{
char name ; // имя точки
public: // открытые члены класса
Dot (char N ) : Coord ( ) { name = N ; } // вызывает конструктор базового класса
~Dot ( ) { cout<<"Delete name \n" ; } // виртуальный деструктор производного класса
} ;
Void main ( )
{
Coord* pC ; // объявляет указатель на базовый класс и
pC = new Dot ('D') ; // передаёт ему адрес объекта производного класса
delete pC ; // удаляет объект производного класса
}
Так как объявленный в производном классе Dot деструктор является виртуальным, то инструкция
delete pC ;
квалифицируется как вызов Dot :: ~Dot ( ) и удаление объекта происходит правильно. При выполнении программа выводит на экран:
Delete name
Delete x , y
Если же сделать деструктор базового класса не является виртуальным, то и деструктор производного класса не будет виртуальным. Значит, использование предыдущей инструкции будет квалифицировано как вызов Coord :: ~Coord ( ), что вызовет удаление только памяти, принадлежащей классу Coord. При выполнении программа выведет на экран:
Delete x , y
В связи с этим можно сформулировать следующие правила:
1. .. виртуальный деструктор целесообразно использовать, если в базовом классе имеются виртуальные функции;
2. .. виртуальные функции целесообразно использовать только в том случае, если программа содержит и базовый, и производный классы;
3. .. нельзя создать виртуальный конструктор.
Абстрактные классы и чисто виртуальные функции
Классы могут быть созданы для того, чтобы предписать протокол взаимодействия с объектами, принадлежащими соответствующему типу. Эти классы называются "абстрактными", потому что никакой объект этого класса не может быть создан. Они существуют исключительно для создания производных классов.
Абстрактный класс – это класс, содержащий, по меньшей мере, одну чисто виртуальную функцию. Производные от него классы должны реализовывать эти чисто виртуальные функции, иначе, если останется хоть одна нереализованная чисто виртуальная функция, такой класс также будет абстрактным. Чисто виртуальная функция объявляется с помощью следующего синтаксиса:
virtual <имя_функции>(<список параметров>) = 0 ;
Рассмотрим пример. Предположим, проектируется иерархия классов, причем базовый класс этой ие-рархии с именем Coord должен обеспечить общие функциональные возможности, но объекты типа Coord являются слишком общими, чтобы быть полезными. В этом случае класс Coord является хорошим кандидатом в абстрактные классы:
Абстрактный базовый класс координат
class Coord // абстрактный базовый класс координат
{
protected: // защищённые члены класса
double x , y ; // координаты
public: // открытые члены класса
Coord ( ) { x = 0 ; y = 0 ; } // конструктор базового класса
virtual void Print ( ) = 0 ; // объявляет чисто виртуальную функцию
} ;
Производный класс точки
class Dot : public Coord // наследник класса координат
{
char name ; // имя точки
public: // открытые члены класса
Dot (char N ) : Coord ( ) { name = N ; } // вызывает конструктор базового класса
// void Print ( ) ; // отсутствие переопределения чисто виртуальной
// функции Print ( ) делает класс абстрактным
} ;
Void main ( )
{
Coord C ; // ошибка: нельзя создать объект абстрактного класса
Dot D ; // ошибка: нельзя создать объект абстрактного класса
}
Путем задания чисто виртуальной функции Print ( ) при проектировании класса Coord разработчик класса добивается того, что любой неабстрактный класс, являющийся производным класса Coord, не может быть реализован без функции Print ( ).
Существуют определенные ограничения на использование абстрактных классов. Они не могут использоваться в качестве:
1. .. переменных, являющихся членами некоторых других классов;
2. .. типов передаваемых в функцию аргументов;
3. .. типов возвращаемых функцией значений;
4. .. типов явных преобразований.
Другое ограничение состоит в том, что если конструктор абстрактного класса вызывает чисто виртуальную функцию, прямо или косвенно, результат непредсказуем.
Чисто виртуальные функции могут быть не только объявлены, но и определены в абстрактном классе. Они могут быть непосредственно вызваны только с использованием следующего синтаксиса:
<имя_абстр_класса> :: <имя_вирт_функции>(<список_параметров>)
К абстрактным классам применимы следующие правила:
· нельзя объявить представитель абстрактного класса;
· абстрактный класс не может использоваться в качестве типа аргумента, передаваемого функции;
· абстрактный класс не может использоваться в качестве типа возвращаемого значения функции;
· нельзя осуществлять явное преобразование типа объекта к типу абстрактного класса;
· можно объявить указатель или ссылку на абстрактный класс.
Дата добавления: 2016-10-17; просмотров: 920;