Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
0495976_C19D7_shpory_s.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
1.82 Mб
Скачать
  1. Виртуальный деструктор. Абстрактные классы.

Практически всегда деструктор делается виртуальным. Делается это для того, чтобы корректно (без утечек памяти) уничтожались объекты не только заданного класса, а и любого производного от него. Например: в игре уровни, звуки и спрайты могут создаваться загрузчиком, а уничтожаться — менеджером памяти, для которого нет разницы между уровнем и спрайтом. Пусть (на C++) есть тип Father и порождённый от него тип Son:

class Father

{

public:

Father() {}

~Father() {}

};

class Son : public Father

{

public:

int* buffer;

Son() : Father() { buffer = new int[1024]; }

~Son() { delete[] buffer; }

};

Нижеприведённый код является некорректным и приводит к утечке памяти.

Father* object = new Son(); // вызывается Son()

delete object; // вызывается ~Father()!!

Однако, если сделать деструктор Father виртуальным:

class Father

{

public:

Father() {}

virtual ~Father() {}

};

class Son : public Father

{private:

int* buffer;

public:

Son() : Father() { buffer = new int[1024]; }

~Son() { delete[] buffer; }};

вызов delete object; приведет в последовательному вызову деструкторов ~Son и ~Father.

Абстрактный класс в объектно-ориентированном программировании — базовый класс, который не предполагает создания экземпляров. Абстрактный класс может содержать (и не содержать[1]) абстрактные методы и свойства. Абстрактный метод не реализуется для класса, в котором описан, однако должен быть реализован для его неабстрактных потомков. Абстрактные классы представляют собой наиболее общие абстракции, то есть имеющие наибольший объем и наименьшее содержание. Абстрактные методы часто являются и виртуальными, в связи с чем понятия «абстрактный» и «виртуальный» иногда путают. На языке программирования C++ абстрактный класс объявляется включением хотя бы одной чистой виртуальной функции, типа virtual _сигнатура_функции_ =0;, которая как и другие может быть заменена. Пример на языке программирования C++:

#include <iostream.h>

class CA { // Абстрактный класс

public:

CA ( void ) { std::cout << "This object of the class "; }

virtual void Abstr ( void ) = 0; // Чистая (пустая) виртуальная функция.

void fun ( void ) { std::cout << "Реализация не будет наследоваться!"; }

~CA () { std::cout << "." << std::endl; } //Вызывается в обр. порядке конструкторов

};

class CB : public CA {

public:

CB ( void ) { std::cout << "CB;"; }

void Abstr ( void ){ std::cout << " call function cb.Abstr();"; } //Подменяющая функция.

void fun ( void ){ std::cout << " call function cb.fun()"; }

~CB () {} // Неверно для абстр. кл. ~CC(){ ~CA(); }

};

class CC : public CA {

public:

CC ( void ) { std::cout << "CC;"; }

void Abstr ( void ) { std::cout << " call function cc.Abstr();"; } //Подменяющая функция.

void fun ( void ) { std::cout << " call function cc.fun()"; }

~CC () {} // Неверно для абстр. кл. ~CC(){ ~CA(); }

};

int main () {

std::cout << "Program:" << std::endl;

CB cb;

cb.Abstr(); cb.fun(); cb.~CB();

CC cc;

cc.Abstr(); cc.fun(); cc.~CC();

return 0;

}

Результат работы программы:

Program:

This object of the class CB; call function cb.Abstr(); call function cb.fun().

This object of the class CC; call function cc.Abstr(); call function cc.fun().

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]