デストラクタをプライベートとして使用することは何ですか?

StackOverflow https://stackoverflow.com/questions/631783

  •  08-07-2019
  •  | 
  •  

質問

デストラクタをプライベートとして使用することは何ですか?

役に立ちましたか?

解決

基本的に、他のクラスにクラスのオブジェクトのライフサイクルを担当させたい場合、またはオブジェクトの破壊を防ぐ理由がある場合はいつでも、デストラクタをプライベートにすることができます。

たとえば、何らかの参照カウントを行っている場合、オブジェクト(または「友人」になっているマネージャー)にそれ自体への参照の数をカウントさせ、その数がゼロをヒットします。プライベート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 は、オブジェクトが参照カウントされ、カウントがゼロになった場合にのみオブジェクト自体によって破棄される必要がある例を示しています。

COMは、この戦略を使用してインスタンスを削除します。 COMはデストラクタをプライベートにし、インスタンスを削除するためのインターフェイスを提供します。

Releaseメソッドがどのように見えるかの例を次に示します。

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

ATL COMオブジェクトは、このパターンの代表的な例です。

ここにすでに存在する回答に追加。プライベートコンストラクタとデストラクタは、 factory を作成する際に非常に役立ちますオブジェクトはヒープに割り当てる必要があります。一般に、オブジェクトは静的メンバーまたは友人によって作成/削除されます。典型的な使用例:

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
}

クラスは単独でのみ削除できます。参照カウントオブジェクトの試行を作成する場合に役立ちます。その後、リリースメソッドのみがオブジェクトを削除できるため、エラーを回避できる可能性があります。

私はあなたが私的なデストラクタについて尋ねていたことを知っています。保護されたものを使用する方法は次のとおりです。メインに余分な機能を追加するクラスへのポインターを介してメインクラスを削除したくないという考えです。
以下の例では、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

Windowsで各モジュールがデバッグヒープ。その問題が正しく処理されない場合 bad < a href = "https://stackoverflow.com/questions/443147/c-mix-new-delete-between-libs">物事が発生する可能性があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top