我需要为基类Base
的所有子类声明finalizing方法finalize()
,该方法应该在销毁期间调用,我的意图是从~Base()
调用纯virtual void Base::finalize() = 0
,但c++禁止这样做。所以我的问题是
我们怎么能强迫后代以正确和初步的方式做一些收尾工作呢?
该代码无法编译:
#include <QDebug>
class Base {
public:
Base(){}
virtual ~Base(){
qDebug("deleting b");
finalize();
}
virtual void finalize() = 0;
};
class A : public Base
{
public:
A(){}
~A(){}
void finalize(){qDebug("called finalize in a");}
};
int main(int argc, char *argv[])
{
Base *b = new A;
delete b;
}
如果我使Base::finalize()
不是纯虚拟的,则从~Base()
调用它,而不将其分派给子级,因为它已经被销毁。
我可以从孩子的析构函数调用finalize(),但问题是如何强制执行。换句话说,我的问题是:是否有可能强制编写基类后代的人使用finalizing方法,好吧,以另一种方式,而不是在文档中对其进行注释?:)
析构函数是释放获取资源的正确位置,但每个类都有责任释放自己的资源。class A
获取的资源不应该(也不能)被class Base
释放。
定义虚拟析构函数允许在删除指向class A
对象的指向class Base
的指针时调用class A
的析构函数
Base* p = new A;
delete p; // Both A and Base destructors are sequencially called!
因此,要实现适当的资源释放,只需要在每个类自己的析构函数中释放每个类的资源。
这就是虚拟析构函数的作用:
class A
{
public:
virtual ~A() {}
};
class B : public A
{
public:
virtual ~B() {}
};
当类型为B
的对象被销毁时,无论是指向B
的指针还是指向A
的指针,都将调用这两个析构函数。首先是B::~B()
,然后是A::~A()
。
使基类析构函数纯虚拟,并带有一个实体,它应该完全按照您的意愿执行。
为什么不使用Base的destructor?这就是析构函数的用途。
搜索RAII,发现c++中最好的东西之一。
大多数习惯使用其他语言的人都必须发现这一点。c++中的资源管理与大多数其他计算机语言完全不同。