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


当前回答

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

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
}

其他回答

Dirkgently错了。下面是一个在堆栈上创建了私有c-tor和d-tor的对象的例子(我在这里使用静态成员函数,但它也可以用friend函数或friend类来完成)。

#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);
};

这段代码将产生输出: 在PrivateCD::TryMe, p._i = 8

这可能是在Windows中处理问题的一种方法,其中每个模块可以使用不同的堆,例如Debug堆。如果这个问题处理不当,就会发生不好的事情。

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

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

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

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

这样的对象永远不能在堆栈上创建。总是在堆上。删除必须通过朋友或会员来完成。一个产品可以使用一个Object层次结构和一个自定义内存管理器——这样的场景可以使用一个私有的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;
}

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

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
}