【问题标题】:delete or virtual delete?删除还是虚拟删除?
【发布时间】:2008-11-12 16:42:36
【问题描述】:

我正在编写一个库和一个演示项目。该项目不关心我使用哪个版本的 lib(我可以使用 sdl、directx 或任何我喜欢的 gfx 后端)。为了得到我做的对象

Obj *obj = libname_newDevice();

现在,我应该使用 delete 还是应该使用 obj->deleteMe();?我问是因为我不完全是在做新的所以我不应该做删除?

我有obj->create(theType);,它返回一个带有 Obj 接口的类。 我真正的问题是我需要libname_deleteDevice(); 还是obj->deleteMe() 很好,因为我在界面中有一个deleteMe?

【问题讨论】:

    标签: c++ virtual


    【解决方案1】:

    由于您正在抽象 libname_newDevice() 内部的创建(我不得不说这不是一个好方法),您应该使用类似 libname_destroyDevice (obj) 的东西来销毁。

    正如 Martin 的评论所建议的,最好将它们放在自定义类的构造函数和析构函数中,您只需在堆栈上创建,编译器会处理其余的。

    【讨论】:

    • 是的,对称性很好。然后你应该将整个东西包装在一个对象中,这两个函数由构造函数/析构函数调用。
    【解决方案2】:

    请尝试澄清您的问题。我完全不清楚。

    • 为什么说图形后端?它与问题相关吗?
    • 您是在问应该如何设计您的库或应该如何使用它?

    最好有一个对象工厂来创建对象。我假设这是libname_newDevice() 的角色。

    该库还应提供删除对象的方法(例如 obj->DeleteMe()libname_Delete(obj) )。

    不要依赖 C++ 的delete:调用者和库可能是使用不同版本的编译器编译的,这会在内存和资源分配方面做不同的事情。因此,如果您的 lib 删除它创建的对象会更安全。

    【讨论】:

    • 我猜图形不相关。具体来说,我想知道我是应该做 libname_Delete() 还是应该做 obj->DeleteMe();我也有一个 obj->create(theType);
    • 如果 lib 删除它创建的对象,会更安全(在 Windows 中)。但你对原因的推理是有缺陷的。
    【解决方案3】:

    我会更进一步。
    如果你使用工厂函数来创建,那么使用工厂函数来销毁可能是合乎逻辑的。除此之外,为了让一切都很好,并且可以安全地打包在一个对象中。

    class ObjWrap
    {
        public:
            ObjWrap()
                :obj(libname_newDevice())
            {}
            ~ObjWrap()
            {    libname_deleteDevice(obj);}
        private:
            ObjWrap(ObjWrap const&);        // Dont copy
            void operator=(ObjWrap const&); // Dont copy
            Obj* obj;
    }; // If you want to copy then you need to extra work on ref counting
       // This may need some form of smart pointer.
    

    【讨论】:

      【解决方案4】:

      我认为最好的方法是尊重 RAII 并拥有一些引用计数包装对象(您甚至可以将 shared_ptr 与自定义释放器一起使用)。

      【讨论】:

        【解决方案5】:

        你肯定不想实现 Obj::deleteMe()。它必须执行以下操作:

        delete this;
        

        当你还在 this->deleteMe() 中时。按照 Jaywalker 的建议,让 destroy 函数以 Obj* 作为参数。

        【讨论】:

        • "删除这个;"可能会使人皮肤爬行,但不一定是坏事。实现自己的引用计数的对象总是必须这样做。例如,请参阅每个“我的第一个 COM 实现”中的 Release()。
        猜你喜欢
        • 2017-11-30
        • 1970-01-01
        • 2021-11-17
        • 2012-12-03
        • 1970-01-01
        • 2011-02-18
        • 2013-02-26
        • 2019-07-24
        • 1970-01-01
        相关资源
        最近更新 更多