Д> кажется мне, что нет... ведь деструктор наследника обязан вызвать деструктор
Д> базового класса. А что ему делать, если у базового класса деструктор не определен?
Чисто виртуальные деструкторы бывают. В этом отношении деструкторы ведут себя так же, как и любые другие функции, за упомянутым исключением, что деструктор базового класса вызывается деструктором потомка вне зависимости от желания программиста.
Д> Д> virtual ~Base() = 0 {};
Д>
Д> как-то странновато такой вариант выглядит...
Этот вариант выглядит, действительно, немного "странновато". Но не потому, что есть определение чисто виртуальной функции, а потому что это определение совмещено с ее объявлением. Текущая версия стандарта подобного не разрешает. Т.е. чисто виртуальные функции можно определять только вне тела класса.
Д> вроде и чисто виртуальный, и в то же время тело определено.
"Чистая виртуальность" и наличие определения вовсе не взаимоисключающие вещи. Чисто виртуальной функцию делают для того, чтобы гарантировать, что (1) она будет обязательно реализована в одном из наследников и что (2) класс будет абстрактным. Чисто виртуальными деструкторы обычно делают именно для (2). Т.е., если, например, в классе больше виртуальных функций нет, но хочется, чтобы класс был абстрактным.
Любая виртуальная функция, в том числе и чисто виртуальная, может быть вызвана невиртуально. Это означает, что при желании чисто виртуальные функции можно определять, но вызвать их можно будет только невиртуально. В случае деструктора этот невиртуальный вызов генерируется компилятором в деструкторах классов-наследников, поэтому даже чисто виртуальные деструкторы обязательно должны быть определены. Например:
class C
{
public:
virtual void f();
virtual void g() = 0;
virtual ~C() = 0;
};
void C::f()
{
}
void C::g()
{
}
void C::~C()
{
}
class D : public C
{
public:
void f();
void g();
~D();
};
void D::f()
{
C::f(); // невиртуальный вызов C::f
}
void D::g()
{
C::g(); // невиртуальный вызов C::g, значит чисто виртуальная C::g должна быть определена
}
void D::~D()
{
// неявный невиртуальный вызов C::~C
}
Posted via RSDN NNTP Server 1.5 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен