我知道在C++中为基类声明虚拟析构函数是一种很好的做法,但是即使对于用作接口的抽象类,声明virtual
析构函数也总是很重要的吗?请提供一些原因和例子。
发布于 2008-11-07 01:01:13
对于一个界面来说,这一点更加重要。您的类的任何用户都可能持有指向接口的指针,而不是指向具体实现的指针。当他们删除它时,如果析构函数是非虚的,他们将调用接口的析构函数(或者编译器提供的默认析构函数,如果您没有指定),而不是派生类的析构函数。即时内存泄漏。
例如
class Interface
{
virtual void doSomething() = 0;
};
class Derived : public Interface
{
Derived();
~Derived()
{
// Do some important cleanup...
}
};
void myFunc(void)
{
Interface* p = new Derived();
// The behaviour of the next line is undefined. It probably
// calls Interface::~Interface, not Derived::~Derived
delete p;
}
发布于 2008-11-07 01:01:39
是的,它总是很重要。派生类可能会分配内存或持有对其他资源的引用,这些资源在对象被销毁时需要清除。如果你没有给你的接口/抽象类提供虚拟析构函数,那么每次你通过基类句柄删除一个派生类实例时,你的派生类的析构函数将不会被调用。
因此,您打开了内存泄漏的可能性
class IFoo
{
public:
virtual void DoFoo() = 0;
};
class Bar : public IFoo
{
char* dooby = NULL;
public:
virtual void DoFoo() { dooby = new char[10]; }
void ~Bar() { delete [] dooby; }
};
IFoo* baz = new Bar();
baz->DoFoo();
delete baz; // memory leak - dooby isn't deleted
发布于 2012-12-27 22:27:55
答案很简单,你需要它是虚拟的,否则基类就不是一个完整的多态类。
Base *ptr = new Derived();
delete ptr; // Here the call order of destructors: first Derived then Base.
如果基类的析构函数不是虚的,那么只会调用基类的析构函数,派生类中的所有数据都不会被删除。
https://stackoverflow.com/questions/270917
复制相似问题