2011-09-19 7 views
4

私はプログラム内の多くのオブジェクトによって使用されるグローバルシングルトンを持っています。これは、プログラムがシャットダウンするときにクラッシュを引き起こします。シングルトン自体がプログラムの最後で破壊された後で、いくつかのオブジェクトのデストラクタで使用されます。ポインタに「削除」が呼び出されたかどうかを知るための移植可能な方法はありますか?私の場合、deleteは(void *)( - 1)へのポインタの値を変更するようですが、これが移植可能かどうかは分かりません。C++ポインタが破壊されているかどうか確認できますか?

+6

いいえ、ありません。 "シングルトン反パターン"と "静的初期化地獄"を探します。 –

+0

'delete'はあなたのポインタの値を変更すべきではありません。 –

+0

おそらくそれはデバッグビルドにありました –

答えて

6

いいえ、C++ポインタが指すオブジェクトが破棄されたかどうかを確認することはできません。

スマートポインタを使用すると、スマートポインタが自動的に処理されます。

+0

これは破壊命令にはあまり役立ちませんしかし、シングルトンで。 –

+0

@AndréCaron:真実ですが、言語の変更を禁止すると、それが役に立ちます。 –

+2

問題は設計されているようです。 –

0

私はそれも未定義の領域だと思っていました。

他のものがすべてクリーンアップされるまであなたのシングルトンを削除しないことをお勧めします。そうでなければ、インスタンスを削除した後にポインタをNULLに設定し、それを確認することができます。リファクタリングが順調であるように私には聞こえる。

0

言われたように、あなたはできません。これを追跡するさまざまな手法がありますが、プラットフォームに依存しています。

まず、あなたの場合の実際の問題は何ですか?シングルトンは、破壊されたときに他のオブジェクトによって使用されています。あなたのシングルトンがCランタイムによって破壊された場合、他のオブジェクトを破壊するものは何ですか?

+0

Cランタイムは他のオブジェクトも破壊します。 –

+0

ここでは設計上の問題があります。Cランタイムによって保証されたデストラクタの特定の順序はありません。シングルトンが破壊されたかどうかを確認するのは適切な解決策ではなく、ハックです。シングルトンの方法は何をしていますか? –

0

シングルトンの削除対象を特定する簡単な方法は、シングルトンのデストラクタを非公開にすることです。その後、削除しようとしている場所でコンパイルエラーが発生するはずです。

1

単純な答え:

  • ポインタを使用しないでください。
  • 古典的なMyersシングルトンを使用します。

次に、あなたのオブジェクトの後に破棄されることを保証するために、オブジェクトの前にインスタンス化されていることを確認してください。オブジェクトの前にインスタンス化されていることを確認するには、オブジェクトのコンストラクタでインスタンスを使用するだけです。

親指の規則:デストラクタでシングルトンを使用する場合。最初にコンストラクタで使用します。

class A 
{ 
    A(); 
    A(A const&); 
    A& operator=(A const&); 
    public: 
     static A& getInstance() // return reference. 
     { 
      static A instance; // Created on first use. 
           // So lazily created when expensive. 

      return instance; // Guaranteed to be destroyed in reverse order of 
           // creation In comparison to other static storage 
           // duration objects. Thus if it is created before 
           // your object It is guaranteed to be correctly 
           // destroyed after your object. 

           // If you want to guarantee it is created before your 
           // object just call A::getInstance() in your constructor 
           // the static member 'instance' will only be created 
           // once and returning a reference is not expensive. 
     } 
     // If you are creating this from the constructor of a global 
     // Then threading becomes a non issues as threads are not started before main 
     // If you are using pthreads or Windows threads you potentially can start them 
     // but it is undefined if they will work so again not your issue. 
}; 
0

このコードは、静的インスタンスの有効期間を追跡します。割り当てをヒープした場合も同様に機能します。 もちろん、インスタンスがまだ構築されていない場合でも、instance()の最初の呼び出し時にインスタンスが作成されます。 しかし、グローバルな静的デストラクタの複雑なメッシュがある場合は、これを使用してインスタンスが破棄されているかどうかを判断できるはずです。

class Thing 
{ 
public: 
    enum State { preConstruction, constructed, destructed }; 
    static const State& singletonState() { return state_;} 
    static Thing& instance() 
    { 
     static Thing instance; 
     return instance; 
    } 
private: 
    Thing() 
    { 
     state_ = constructed; 
    } 
    ~Thing() 
    { 
     state_ = destructed; 
    } 
    static State state_; 
}; 

Thing::State Thing::state_ = Thing::preConstruction; 
関連する問題