gpt4 book ai didi

c++ - 删除是否适用于指向基类的指针?

转载 作者:IT老高 更新时间:2023-10-28 14:00:26 26 4
gpt4 key购买 nike

您是否必须传递 delete 与 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 析构函数中隐含的删除运算符来做正确的事情。

这可能行得通吗?我的直觉说不,因为指针不会有相同的地址。另一方面, dynamic_cast 应该可以工作,因此编译器在某个地方存储了足够的信息来解决这个问题。


感谢您的帮助,所有回答和评论的人。我已经知道虚拟析构函数的重要性,如我的示例所示;看到答案后,我稍微思考了一下,并意识到虚拟析构函数的 全部原因就是这种情况。因此它必须工作。我被缺少将指针转换回原始指针的可见方法而感到震惊。更多的思考让我相信有一种看不见的手段,我推测析构函数正在返回真正的删除指针以释放。当我在 ~Base:

中看到这一行时,调查来自 Microsoft VC++ 的编译代码证实了我的怀疑
mov eax, DWORD PTR _this$[ebp]

跟踪汇编程序发现这是传递给删除函数的指针。谜团解开了。

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

最佳答案

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

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

关于c++ - 删除是否适用于指向基类的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/294927/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com