通过接口删除对象 [英] deleting an object via interface
问题描述
嗨
我有一个实现接口Base
的类Derived
,类似这样
Hi
I have a class Derived
which implements an interface Base
, something like this
class Base {
public:
virtual void foo () = 0;
};
class Derived : public Base {
public:
Derived (int i = 5) {
data = new double [i];
}
~Derived () {
foo ();
}
void foo () {
if (data) {
delete []data;
}
}
private:
double *data; // an array
};
如您所见,此处的foo会执行清理例程.现在,我创建一个类Derived
的实例并将其存储到类型为Base
的变量中:
The foo here as you can see does the cleaning up routine. Now I create an instance of class Derived
and store it to variable of type Base
:
int n;
Base *base;
n = 1024 * 1024 * 8; // some random big number
base = new Derived (n);
delete base;
此后,尽管变量base
已经无效,但仍未回收使用的资源.我注意到它甚至都没有去~Derived()
的析构函数,因此资源仍然存在.我不知道为什么,也许有人可以解释一下.
过了一会儿,我想出了一个解决方案:
After this, the used resources still not reclaimed, although the variable base
is already invalid. I notice that It doesn''t even go to the destructor of ~Derived()
hence the resources is still there. I don''t know why, maybe someone can explain this.
After a little while I come up with a solution:
int n;
Base *base;
n = 1024 * 1024 * 8;
base = new Derived (n);
Derived *p;
p = dynamic_cast<Derived*>(base);
if (p) {
delete p;
}
除此以外,还有其他解决方案吗?
Are there any other solution than this?
推荐答案
您的解决方案可以使用,但它是人为的,不利于维护.不要这样做.
而是添加一个虚拟析构函数Base::~Base
.
在这种情况下,即使在delete
中使用的编译时类型为Base
,也会调用析构函数Derived::~Derived
.基于此编译时类,对析构函数Base::~Base
的调用将首先通过 late绑定分派给Derived::~Derived
,然后,由于自动调用基类析构函数的机制,Base::~Base
将被调用.
尝试一下:我在发布答案之前测试了此代码.
并修复一个小缺陷:将函数foo
设为私有.
—SA
Your solution would work, but it is artificial and bad for maintenance. Don''t do such things.
Instead, add a virtual destructorBase::~Base
.
In this case, the destructorDerived::~Derived
will be called even if your compile-time type you use indelete
isBase
. Based on this compile-time class, the call to the destructorBase::~Base
will be dispatched toDerived::~Derived
through late binding first, and then, because of the mechanism of automatic call base class destructor,Base::~Base
will be called.
Try it: I tested this code before posting the answer.
And fix one minor flaw: make the functionfoo
private.
—SA
这篇关于通过接口删除对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!