【发布时间】:2014-11-27 18:58:15
【问题描述】:
我的问题是你认为下面显示的代码安全吗?这段代码能否按原样生成运行时故障,例如:
__PureVirtualCalled() at 0x9000000007ef90c?顺便说一句,我在 GNU Linux(64 位)上使用 g++ 4.3.2 编译了这段代码。输出是:
~derived called. ~base() called. ~base() called. foo() called.请注意,下面给出的代码只是我为解释问题而编写的一个小程序。真正的类实际上是一个引用计数器的实现,它仅在其计数降至零时才释放自己。手动调用析构函数的原因是为了避免虚函数调用的开销(引用计数器类派生自抽象计数器类)。可以通过显式指定要调用的函数来抑制虚拟调用,尤其是在该类是派生最多的类的情况下。但是,这显然不适用于虚拟析构函数。
更多信息,出现上述错误的实际应用程序是多线程应用程序。
请注意,我试图解释为什么运行时会引发上述错误。它会间歇性地这样做。
代码
#include <iostream>
class base {
public:
virtual ~base() {
std::cout << "~base() called." << std::endl;
}
virtual void dispose() = 0;
void foo() {
dispose();
std::cout << "foo() called." << std::endl;
}
};
class derived : public base {
public:
~derived() {
std::cout << "~derived called." << std::endl;
}
void dispose() {
// Intention here is to suppress the virtual function call.
this->derived::~derived();
delete this;
}
};
int main() {
base* ptr = new derived;
ptr->foo();
return 0;
}
【问题讨论】:
-
你为什么要这样做(即你想要达到什么目的)?
-
我看不出它是如何产生 PureVirtualCalled 但肯定会产生大量其他问题。当您有析构函数时,拥有
dispose()有什么意义?为什么你打电话给delete this? -
@AdrianoRepetti 他可能正在尝试实现一些垃圾收集器垃圾。
-
显然不是。您正在删除两次(您的代码 + 编译器)同一个对象,这将导致内存泄漏。只要有基类的虚析构函数,就不需要特意删除。
-
您试图通过...实现一个虚函数来抑制虚函数调用?
标签: c++ virtual destructor