当前位置:  开发笔记 > 编程语言 > 正文

delete是否适用于指向基类的指针?

如何解决《delete是否适用于指向基类的指针?》经验,为你挑选了1个好方法。

您是否必须传递删除new返回的相同指针,或者您可以将指针传递给其中一个类基类型?例如:

class Base
{
public:
    virtual ~Base();
    ...
};

class IFoo
{
public:
    virtual ~IFoo() {}
    virtual void DoSomething() = 0;
};

class Bar : public Base, public IFoo
{
public:
    virtual ~Bar();
    void DoSomething();
    ...
};

Bar * pBar = new Bar;
IFoo * pFoo = pBar;
delete pFoo;

当然,这大大简化了.我真正想要做的是创建一个充满boost :: shared_ptr的容器,并将其传递给一些代码,这些代码在完成后将从容器中删除它.这段代码对Bar或Base的实现一无所知,并且依赖于shared_ptr析构函数中隐含的delete运算符来做正确的事情.

这可能有用吗?我的直觉说不,因为指针不会有相同的地址.另一方面,dynamic_cast 应该可以工作,所以编译器正在存储足够的信息来解决它.


感谢您的帮助,所有回答和评论的人.我已经知道虚拟析构函数的重要性,如我的例子所示; 在看到答案后我稍微考虑了一下,并意识到虚拟析构函数的全部原因就是这个确切的场景.因此它必须工作.由于没有将指针转换回原件的可见方法,我被抛出了.多一点思考让我相信有一种看不见的方法,我理论上析构函数正在返回真正的删除指针以释放.当我在~Base中看到这一行时,调查来自Microsoft VC++的编译代码证实了我的怀疑:

mov eax, DWORD PTR _this$[ebp]

跟踪汇编程序显示这是传递给delete函数的指针.谜团已揭开.

我已经修复了将虚拟析构函数添加到IFoo的示例,这是一个简单的疏忽.再次感谢所有指出的人.



1> Adam Rosenfi..:

是的,它将起作用,当且仅当基类析构函数是虚拟的时,您已经为Base基类而不是IFoo基类.如果基类析构函数是虚拟的,那么当您调用operator delete基类指针时,它使用动态调度来通过在虚函数表中查找派生类析构函数来找出如何删除该对象.

在你的多重继承的情况下,它只有在你删除它的基类有一个虚拟析构函数时才会起作用; 可以让其他基类没有虚拟析构函数,但前提是你不尝试通过其他基类指针删除任何派生对象.


即使没有虚拟析构函数,实际内存也可能被释放.
问题是您没有在需要的地方包含虚拟析构函数.你在Base中包含了一个虚拟析构函数,但是在IFoo中没有.您的delete语句调用IFoo中的非虚拟析构函数,因此它不会过滤到Bar,不会过滤回Base,也会泄漏内存.
我担心JaredPar和Evan对这个例子的看法不够.
推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有