代码之家  ›  专栏  ›  技术社区  ›  Mark Ransom

delete与指向基类的指针一起工作吗?

  •  43
  • Mark Ransom  · 技术社区  · 16 年前

    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;
    

    这可能行吗?我的直觉是否定的,因为指针不会有相同的地址。另一方面,动态的演员阵容<巴*>应该可以工作,所以编译器在某个地方存储了足够的信息来解决这个问题。


    谢谢你的帮助,所有回答和评论的人。我已经知道虚拟析构函数的重要性,如我的示例所示;看到答案后,我想了想,意识到 对于虚拟析构函数来说,就是这样一种情况。因此,它必须发挥作用。由于没有一种可见的方法将指针转换回原来的指针,我感到很困惑。再多想一想,我就相信有一种看不见的方法,我推断析构函数返回了delete释放的真正指针。当我在~Base中看到这一行时,调查Microsoft VC++编译的代码证实了我的怀疑:
    mov eax, DWORD PTR _this$[ebp]
    

    2 回复  |  直到 16 年前
        1
  •  63
  •   Adam Rosenfield    16 年前

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

        2
  •  3
  •   Michael Burr    16 年前

    这与您给出的示例无关,但既然您提到您对 shared_ptr 删除其拥有的对象时的行为,您可能有兴趣使用 共享ptr 's'deleter'。

    如果对象属于 共享ptr 需要特殊处理删除时,您可以为任何特定的 shared_ptr<> . 删除器不是类型的一部分,它是 共享\u ptr<&燃气轮机; 共享\u ptr<&燃气轮机; 共享\u ptr<&燃气轮机; 删除者:

    自定义DealLocator允许工厂 共享ptr 到 将用户与其内存隔离 deallocator不是该类型的一部分, 改变分配策略确实有好处 不中断源代码或二进制代码 兼容性,并且不需要 客户端重新编译。例如,一个 归还 共享ptr 分配对象和其他变体 允许 共享ptr 用作

    如果你能修改它,它将是最干净的 IFoo 伊福 引用或指针。但是如果你被一个 伊福 无法更正,那么如果要使用 shared_ptr<IFoo> 在您的容器中,但让它指向 Bar 共享ptr Bar* 然后执行删除操作。Downcast被认为是一种糟糕的形式,但这种技术可能在绑定中使用。