Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Что это такое и как можно использовать?


Автор: gr1fon 17.8.2007, 15:05
class A
{
public:
virtual ~A() = 0;
};

Автор: Partizan 17.8.2007, 15:16
виртуальные деструкторы используют для того чтобы гарантировать в каждом из наследников реализацию деструктора....

Автор: bsa 17.8.2007, 15:21
Это абстрактный класс. Он не разрешает создание объектов. Он требует, чтобы были потомки со своими деструкторами (точнее, хотя бы один потомок).

Автор: Fazil6 17.8.2007, 15:32
Цитата

 Что это такое и как можно использовать?

это сделано для того, чтобы класс был абстрактным (нельзя создавать экземпляры A) и использовался как базовый. Вообще-то здесь довольно бессмысленный класс, так как он вроде как должен быть базовым, но интерфейса никакого не объявлено. Кстати реализация деструктора тоже должна быть в этом классе A/

Цитата(Partizan @  17.8.2007,  15:16 Найти цитируемый пост)
виртуальные деструкторы используют для того чтобы гарантировать в каждом из наследников реализацию деструктора....

хм... интересная мысль... Вообще-то деструктор виртуальный нужен для правильного вызова деструкторов при разрушении объекта при полиморфном использовании и совсем не обязательно явно реализовывать деструкторы в наследниках, даже если в базовом он виртуальный.

Автор: Dreamer_0x01 17.8.2007, 15:32
Как абсолютно правильно уже указали, это абстрактный класс. 
Запись вида 
Код

virtual [тип функции] func([параметры]) = 0;

называется "чисто виртуальной функцией" (pure virtuale).
При наличии хотя бы одной такой функции класс становится абстрактным. Это означает, что вы не можете создавать объекты такого класса, а виртуальные функции обязательно должны быть переопределены в производных классах. Однако, вы можете пользоваться указателем на объект такого класса при реализации полиморфности. 

Деструктор же делается виртуальным для того, чтобы при уничтожении объекта базового класса был вызван деструктор производного класса.

Автор: zkv 17.8.2007, 15:38
Цитата(Fazil6 @  17.8.2007,  15:32 Найти цитируемый пост)
Кстати реализация деструктора тоже должна быть в этом классе A

можно пояснить? Какая реализация, если метод (деструктор) объявлен абстрактным?
Честно говоря, не сталкивался с применением абстрактных деструкторов...

Автор: Partizan 17.8.2007, 15:39
Fazil6, согласен

Автор: sentry 17.8.2007, 15:39
Цитата(Partizan @  17.8.2007,  16:46 Найти цитируемый пост)
виртуальные деструкторы используют для того чтобы гарантировать в каждом из наследников реализацию деструктора....

Цитата(bsa @  17.8.2007,  16:51 Найти цитируемый пост)
Он требует, чтобы были потомки со своими деструкторами (точнее, хотя бы один потомок).

Переопределять чисто виртуальный деструктор в производных классах не обязательно...
Код

class A {
public:
  virtual ~A() = 0;
};

A::~A() {}

class B: public A {};

Это прекрасно компилится.

Автор: Fazil6 17.8.2007, 15:54
Цитата(zkv @  17.8.2007,  15:38 Найти цитируемый пост)
можно пояснить? Какая реализация, если метод (деструктор) объявлен абстрактным?


оно же не скомпилится если нет реализации. Хоть базовый клас и абстрактный, но при удалении потомка последним должен вызываться деструктор базового, поэтому реализован он должен быть полюбому. Например так
Код

class A
{
public:
virtual ~A() = 0 {} ;
};


Цитата(zkv @  17.8.2007,  15:38 Найти цитируемый пост)
Честно говоря, не сталкивался с применением абстрактных деструкторов...

ну вобщем обычно так делают если класс д.б. абстрактным, но, например, нету других методов виртуальных или все они имеют рееализацию в базовом классе

Автор: zkv 17.8.2007, 15:56
накидал пример
Код

#include <cstdio>

class A 
{
public:
  virtual ~A() = 0;
  virtual int f() = 0;
};

A::~A() {}

int A::f()
{
    return 1;
}

class B: public A 
{
public:
    virtual int f();
};

int B::f()
{
    return 0;
}

int main(int argc, char* argv[])
{
    B b;
    printf( "%d", b.f() ); 
    printf( "%d", b.A::f() ); 
    getc( stdin );
    return 0;
}

выяснилось:
 - объявление метода абстрактным говорит о том, что у него может (я считал, что должно) отсутствовать определение 
 - 
Цитата(sentry @  17.8.2007,  15:39 Найти цитируемый пост)
Переопределять чисто виртуальный деструктор в производных классах не обязательно...
 те не специальные методы переопределять обязательно, а деструктор нет...
а, он (компилятор) его по умолчанию туда затолкает наверное.

Автор: Fazil6 17.8.2007, 16:00
Цитата(zkv @  17.8.2007,  15:56 Найти цитируемый пост)
те не специальные методы переопределять обязательно, а деструктор нет...

ну просто компиллятор сам сгенерит деструктор если его нет

Автор: sentry 17.8.2007, 16:14
Цитата(Fazil6 @  17.8.2007,  17:30 Найти цитируемый пост)
ну просто компиллятор сам сгенерит деструктор если его нет

Да, компилятор автоматически создает определение деструктора для каждого класса, не имеющего его определения. 
Кстати, именно поэтому производные классы не являются абстрактными.
Насколько я понимаю, чисто виртуальный деструктор нужен только для того, чтобы нельзя было создать экземпляр базового класса. И все.

Автор: UnrealMan 17.8.2007, 22:13
Цитата(Fazil6 @ 17.8.2007,  15:54)
поэтому реализован он должен быть полюбому. Например так
Код

class A
{
public:
virtual ~A() = 0 {} ;
};


Вот так стандарт как раз-таки не разрешает:

Цитата(ISO/IEC 14­882:2003(E) §10.4 Abstract classes)
[Note: a function declaration cannot provide both a pure-specifier and a definition
—end note] [Example:
    struct C {
        virtual void f() = 0 { }; // ill-formed
};


Добавлено через 3 минуты и 36 секунд
Цитата(sentry @  17.8.2007,  16:14 Найти цитируемый пост)
Да, компилятор автоматически создает определение деструктора для каждого класса, не имеющего его определения. 

Не имеющего его объявления smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)