通过接口删除对象 [英] deleting an object via interface

查看:67
本文介绍了通过接口删除对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我有一个实现接口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 destructor Base::~Base.

In this case, the destructor Derived::~Derived will be called even if your compile-time type you use in delete is Base. Based on this compile-time class, the call to the destructor Base::~Base will be dispatched to Derived::~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 function foo private.

—SA


这篇关于通过接口删除对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆