删除工作指针基类?
你必须通过删除新的返回相同的指针,或者你可以传递一个指针到一个基types的指针? 例如:
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;
当然这大大简化了。 我真正想要做的是创build一个充满boost :: shared_ptr的容器,并将其传递给一些代码,当它完成时将它从容器中删除。 这段代码对Bar或Base的实现一无所知,并且依赖于shared_ptr析构函数中的隐含的delete操作符来做正确的事情。
这可能工作吗? 我的直觉说不,因为指针不会有相同的地址。 另一方面,dynamic_cast <Bar *>应该可以工作,所以编译器在某处存储了足够的信息来解决这个问题。
感谢帮助,每个人都回答和评论。 我已经知道虚拟析构函数的重要性,如我的示例所示; 看到答案后,我稍微想了一下,发现虚拟析构函数的全部原因就是这个确切的情况。 因此它必须工作。 由于没有将指针转换回原来的可见方法,我被抛出了。 多一点思考使我相信有一种看不见的手段,并且我推理出析构函数正在返回真正的指针以便删除。 调查从Microsoft VC ++编译的代码证实了我的疑虑,当我在〜基地看到这行:
mov eax, DWORD PTR _this$[ebp]
跟踪汇编器显示,这是指针被传递给删除function。 谜团已揭开。
我已经修正了这个例子,将虚拟析构函数添加到IFoo,这是一个简单的疏忽。 再次感谢所有指出的人。
是的, 当且仅当基类析构函数是虚拟的时候,它才会起作用,你已经为Base
基类而不是IFoo
基类做过。 如果基类析构函数是虚拟的,那么当你调用基类指针的operator delete
时,它会使用dynamic调度来查找如何通过查找虚函数表中的派生类析构函数来删除对象。
在你的多重inheritance的情况下,它只会在你正在删除的基类有一个虚拟的析构函数时才起作用。 其他基类没有虚拟析构函数是可以的,但前提是您不要试图通过其他基类指针删除任何派生对象。
这与你给出的例子没有关系,但是既然你提到你真的对shared_ptr
在删除它拥有的对象时的行为感兴趣,你可能会对使用shared_ptr
的“deleter”感兴趣。
如果shared_ptr
拥有的对象在删除时需要特殊处理,则可以为任何特定的shared_ptr<>
指定一个“deleter”。 删除器不是types的一部分,它是一个shared_ptr<>
实例的属性,所以你的shared_ptr<>
对象的容器可以有一些具有不同删除器的对象。 以下是Boost文档对shared_ptr<>
deleter的说明:
自定义释放器允许一个工厂函数返回一个
shared_ptr
来隔离用户的内存分配策略。 由于释放器不是types的一部分,因此更改分配策略不会中断源或二进制兼容性,也不需要客户端重新编译。 例如,当将一个shared_ptr
返回给一个静态分配的对象时,一个“no-op”释放器是有用的,而其他的变化允许shared_ptr
被用作另一个智能指针的包装器,从而降低互操作性。
如果你可以修改IFoo
有一个虚拟析构函数,因为你打算通过一个IFoo
引用或指针删除它的子类的对象,这将是最干净的。 但是如果你坚持使用无法纠正的IFoo
,那么如果你想在你的容器中使用shared_ptr<IFoo>
,但是把它指向一个Bar
,你可以创build一个带有删除器的shared_ptr
实例,一个Bar*
然后执行删除操作。 Downcasts被认为是不好的forms,但是这种技术可能是你可以在绑定中使用的东西。