回答:
基本的に、他のクラスにクラスのオブジェクトのライフサイクルを担当させたい場合、またはオブジェクトの破棄を防ぐ理由がある場合はいつでも、デストラクタをプライベートにできます。
たとえば、なんらかの参照カウント処理を行っている場合、オブジェクト(または「フレンド」になっているマネージャー)がそれ自体への参照数をカウントし、その数がゼロになったときにそれを削除することができます。プライベートdtorは、それへの参照がまだあるときに、他のユーザーがそれを削除できないようにします。
別の例として、データベース接続が開いている、ファイルが書き込まれているなど、プログラムの他の条件に応じて、それを破壊したり破壊したりするマネージャー(またはそれ自体)を持つオブジェクトがある場合はどうでしょうか。クラスまたはマネージャーに「request_delete」メソッドを設定して、その条件を確認すると、削除または拒否され、何が行われたかを示すステータスが返されます。これは、単に「削除」を呼び出すよりもはるかに柔軟です。
このようなオブジェクトをスタック上に作成することはできません。常にヒープ上。そして、削除は友人やメンバーを介して行われる必要があります。製品では、単一のオブジェクト階層とカスタムメモリマネージャーを使用できます。このようなシナリオでは、プライベート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;
}
ユーザーがデストラクタにアクセスできないようにする場合、つまり、オブジェクトを他の方法でのみ破棄する場合。
http://blogs.msdn.com/larryosterman/archive/2005/07/01/434684.aspxは例を示しています。この場合、オブジェクトは参照カウントされ、カウントがゼロになったときにのみオブジェクト自体によって破棄されます。
ここにすでに存在する答えに追加します。プライベートコンストラクターとデストラクタは、作成されたオブジェクトをヒープに割り当てる必要があるファクトリを実装するときに非常に役立ちます。オブジェクトは、通常、静的メンバーまたは友達によって作成/削除されます。一般的な使用例:
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
}
クラスはそれ自体でのみ削除できます。参照カウントオブジェクトの試行を作成する場合に役立ちます。次に、オブジェクトを削除できるのはreleaseメソッドだけであり、おそらくエラーを回避するのに役立ちます。
私はあなたが民間の破壊者について尋ねていたのを知っています。これが保護されたものの使い方です。アイデアは、メインに追加の機能を追加するクラスへのポインターを通じてメインクラスを削除したくないということです。
以下の例では、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(){}
};
ひどく間違っています。これは、スタック上に作成されたプライベート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);
};
このコードは出力を生成します:PrivateCD :: TryMeの内部、p._i = 8