C++ 将析构函数设为私有有什么用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/631783/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:24:28  来源:igfitidea点击:

What is the use of having destructor as private?

c++privatedestructor

提问by yesraaj

What is the use of having destructor as private?

将析构函数设为私有有什么用?

采纳答案by Paul Tomblin

Basically, any time you want some other class to be responsible for the life cycle of your class' objects, or you have reason to prevent the destruction of an object, you can make the destructor private.

基本上,任何时候您希望某个其他类负责您的类对象的生命周期,或者您有理由阻止对象的销毁,您都可以将析构函数设为私有。

For instance, if you're doing some sort of reference counting thing, you can have the object (or manager that has been "friend"ed) responsible for counting the number of references to itself and delete it when the number hits zero. A private dtor would prevent anybody else from deleting it when there were still references to it.

例如,如果您正在做某种引用计数的事情,您可以让对象(或已被“好友”处理的管理器)负责计算对自身的引用数量,并在数量达到零时将其删除。当仍然有对它的引用时,私有 dtor 将阻止其他任何人删除它。

For another instance, what if you have an object that has a manager (or itself) that may destroy it or may decline to destroy it depending on other conditions in the program, such as a database connection being open or a file being written. You could have a "request_delete" method in the class or the manager that will check that condition and it will either delete or decline, and return a status telling you what it did. That's far more flexible that just calling "delete".

再举一个例子,如果你有一个对象,它有一个管理器(或它本身),根据程序中的其他条件,如数据库连接打开或文件正在写入,可能会销毁它或拒绝销毁它。您可以在类或管理器中使用“request_delete”方法来检查该条件,它将删除或拒绝,并返回一个状态,告诉您它做了什么。这比仅调用“删除”要灵活得多。

回答by dirkgently

Such an object can never be created on the stack. Always on the heap. And deletion has to be done via a friend or a member. A product may use a single Object hierarchy and a custom memory-manager -- such scenarios may use a private dtor.

永远不能在堆栈上创建这样的对象。总是在堆上。删除必须通过朋友或成员完成。产品可能使用单个对象层次结构和自定义内存管理器——此类场景可能使用私有 dtor。

#include <iostream>
class a {
    ~a() {}
    friend void delete_a(a* p);
};


void delete_a(a* p)  {
    delete p;
}

int main()
{
    a *p = new a;
    delete_a(p);

    return 0;
}

回答by Michael

When you do not want users to access the destructor, i.e., you want the object to only be destroyed through other means.

当您不希望用户访问析构函数时,即您希望对象只能通过其他方式被销毁。

http://blogs.msdn.com/larryosterman/archive/2005/07/01/434684.aspxgives an example, where the object is reference counted and should only be destroyed by the object itself when count goes to zero.

http://blogs.msdn.com/larryosterman/archive/2005/07/01/434684.aspx给出了一个例子,其中对象是引用计数的,并且只有当计数变为零时才应该由对象本身销毁。

回答by Vinay

COM uses this strategy for deleting the instance. COM makes the destructor private and provides an interface for deleting the instance.

COM 使用此策略删除实例。COM 将析构函数设为私有并提供用于删除实例的接口。

Here is an example of what a Release method would look like.

下面是一个 Release 方法的示例。

int MyRefCountedObject::Release() 
{
 _refCount--;
 if ( 0 == _refCount ) 
 {
    delete this;
    return 0;
 }
 return _refCount;
}

ATL COM objects are a prime example of this pattern.

ATL COM 对象是这种模式的主要例子。

回答by nav

Adding to the answers already present here; private constructors and destructors are quite useful while implementing a factorywhere the created objects are required to be allocated on the heap. The objects would, in general, be created/deleted by a static member or friend. Example of a typical usage:

添加到这里已经存在的答案;在实现需要在堆上分配创建的对象的工厂时,私有构造函数和析构函数非常有用。通常,对象将由静态成员或朋友创建/删除。典型用法示例:

class myclass
{
public:
    static myclass* create(/* args */)  // Factory
    {
        return new myclass(/* args */);
    }

    static void destroy(myclass* ptr)
    {
        delete ptr;
    }
private:
    myclass(/* args */) { ... }         // Private CTOR and DTOR
    ~myclass() { ... }                  // 
}

int main ()
{
    myclass m;                          // error: ctor and dtor are private
    myclass* mp = new myclass (..);     // error: private ctor
    myclass* mp = myclass::create(..);  // OK
    delete mp;                          // error: private dtor
    myclass::destroy(mp);               // OK
}

回答by Roland Rabien

The class can only be deleted by itself. Useful if you are creating some try of reference counted object. Then only the release method can delete the object, possibly helping you avoid errors.

该类只能自行删除。如果您正在创建一些引用计数对象的尝试,则很有用。那么只有 release 方法可以删除对象,可能会帮助您避免错误。

回答by misicd

dirkgently is wrong. Here is an example of object with private c-tor and d-tor created on stack (I'm using static member function here, but it can be done with friend function or friend class as well).

确实是错误的。这是一个在堆栈上创建私有 c-tor 和 d-tor 的对象示例(我在这里使用静态成员函数,但也可以使用友元函数或友元类来完成)。

#include <iostream>

class PrivateCD
{
private:
    PrivateCD(int i) : _i(i) {};
    ~PrivateCD(){};
    int _i;
public:
    static void TryMe(int i)
    {
        PrivateCD p(i);
        cout << "inside PrivateCD::TryMe, p._i = " << p._i << endl;
    };
};

int main()
{
    PrivateCD::TryMe(8);
};

This code will produce output: inside PrivateCD::TryMe, p._i = 8

此代码将产生输出: inside PrivateCD::TryMe, p._i = 8

回答by Mykola Golubyev

I know you were asking about private destructor. Here is how I use protected ones. The idea is you don't want to delete main class through the pointer to class that adds extra functionality to the main.
In the example below I don't want GuiWindow to be deleted through a HandlerHolder pointer.

我知道你在问私有析构函数。这是我如何使用受保护的。这个想法是您不想通过指向向主添加额外功能的类的指针删除主类。
在下面的示例中,我不希望通过 HandlerHolder 指针删除 GuiWindow。

class Handler
{
public:
    virtual void onClose() = 0;
protected:
    virtual ~Handler();
};

class HandlerHolder
{
public:
    void setHandler( Handler* );
    Handler* getHandler() const;
protected:
    ~HandlerHolder(){}
private:
    Handler* handler_;
};

class GuiWindow : public HandlerHolder
{
public:
    void finish()
    {
        getHandler()->onClose();
    }

    virtual ~GuiWindow(){}
};

回答by Jared Oberhaus

It might be a way to deal with the problem in Windows where each module can use a different heap, such as the Debugheap. If that problem isn't handled correctly badthingscan happen.

它可能是处理 Windows 中每个模块可以使用不同堆(例如调试堆)的问题的一种方法。如果这个问题没有正确处理不好的事情可能发生。