C++ 使用私有析构函数删除动态分配的对象

C++ 使用私有析构函数删除动态分配的对象,c++,destructor,dynamic-memory-allocation,C++,Destructor,Dynamic Memory Allocation,所以我遇到了一个代码片段,它演示了如果我们想要强制动态分配任何类对象,我们应该将其析构函数设置为私有的 我试过了,是的,它不允许在堆栈上实例化对象。但当我实例化一个动态分配的实例并尝试删除该对象(否则会导致泄漏)时,我不断收到关于析构函数是私有的警告 如何正确管理具有私有析构函数的动态分配对象的内存?与访问任何其他私有成员函数一样,必须在成员或友元函数中执行此操作。例如: class foo { ~foo(){} public: static void del(const foo

所以我遇到了一个代码片段,它演示了如果我们想要强制动态分配任何类对象,我们应该将其析构函数设置为私有的

我试过了,是的,它不允许在堆栈上实例化对象。但当我实例化一个动态分配的实例并尝试删除该对象(否则会导致泄漏)时,我不断收到关于析构函数是私有的警告


如何正确管理具有私有析构函数的动态分配对象的内存?

与访问任何其他私有成员函数一样,必须在成员或友元函数中执行此操作。例如:

class foo {
    ~foo(){}
public:
    static void del(const foo* ptr)
    {
        delete ptr;
    }
};
或者更好,强制客户端使用智能指针:

class foo {
    ~foo(){}
    struct deleter {
        void operator()(const foo* ptr)
        {
            delete ptr;
        }
    };
public:
    static std::unique_ptr<foo, deleter> make(/*args*/)
    {
        return {new foo(/*args*/), {}};
    }
};
class-foo{
~foo(){}
结构删除器{
void运算符()(常量foo*ptr)
{
删除ptr;
}
};
公众:
静态标准::唯一的ptr生成(/*args*/)
{
返回{newfoo(/*args*/),{};
}
};
这里有一个例子:

class Example {
public:
    void kill_me() { // a public function
        delete this; // is allowed to delete
    }
private:
    ~Example() {}    // private destructor
};

int main() {
    Example* e = new Example;
    e->kill_me();
}

强制动态分配对象的唯一原因是它需要以某种方式管理自己的生命周期。否则,创建对象的代码将负责管理其生存期——由于自动存储持续时间是一种有效的生存期管理策略,因此不应故意禁用它

因此,我假设您的对象管理自己的生命周期;例如,它可能维护一个引用计数,然后在引用计数变为0时调用
release()
方法中的
delete this
。那么,作为对象的用户,“如何正确管理对象的生命周期”这个问题的答案是“正确使用对象”,以便对象在适当的时候释放自己


例如,可以使用带有自定义删除器的
std::unique\u ptr
来确保在作用域退出时调用对象的
release()
,防止任何引用泄漏。

提供删除功能可以在访问控制范围内工作,但会强制类的用户在任何地方使用自定义删除器。与标准默认删除器交朋友更为简洁:

struct Foo {
private:
    friend std::default_delete<Foo>;
    ~Foo() = default;
};

auto p = std::make_unique<Foo>(); // Works out of the box
structfoo{
私人:
friend std::默认值_delete;
~Foo()=默认值;
};
自动p=std::使_唯一();//开箱即用

hello@eerorika:谢谢您的快速回答。它起作用了。我试过了。我可以知道您选择将该方法设置为静态的具体原因吗?@User9102d82虽然它定义得很好,可以
删除此
,但并不是每个人都知道这一点,而且它不寻常,容易引起混淆。@Quentin不需要这样做
foo::deleter
foo
的成员,因此它可以访问
foo
的所有私有成员。@Brian,自C++11以来。我很困惑以前从来没有遇到过那个地方…很好。比我的想法更简单。请注意,这并不严格符合要求,因为
std::default_delete
允许调用一些内部自由函数,其中包含实际的
delete
调用(此时析构函数将无法访问)。@Brian说得很对,但这看起来像是一个标准的疏忽。
std::default\u delete
的专门化可以解决这样的问题。这一点很好。我确实试着像你描述的那样删除对象,但它仍然发生泄漏。但是指针实际上是如何被删除的呢?我在哪里可以读到这些。@User9102d82对不起,我不确定我是否理解你的意思。关于“好理由”部分,你是对的。我正在研究ACE Reactor框架,它建议只动态分配对象(由于Reactor的内部工作),因此我第一次遇到这个问题。+1供您输入和解释。了解更多有关情况的情况是有帮助的。非常感谢。