2013-11-27 9 views
6

私はので、私は方法)(ストップからデストラクタを呼び出す必要が怒鳴るクラスメソッドからデストラクタを呼び出すことはできますか?

class Thread { 
public: 
    Thread(); 
    ~Thread(); 
    void start(); 
    void stop(); 
} 

ようThreadクラスを持って、それはそれを行うには良い方法ですか?

+3

いいえ、オブジェクトの寿命が終わったときはどうなりますか?コーナーケースでは機能するかもしれませんが、コーナーケースでのみ動作するようにクラスを制限したいのですか? – juanchopanza

+0

'これを削除する; '(スタックvarの場合)、それは非常に危険です。なぜそれが欲しいのですか? 'stop'を呼び出した後にオブジェクトを'削除 'できないか、スマートポインタを使用できませんか?または変数をスタックするだけですか? –

+0

@KirilKirov:どのスタックに 'Thread'があるのですか?おそらく他のスレッドのスタックではなく、それ自身のスタックではありません。 – MSalters

答えて

5

はい

delete this; 

しかし、注意してください。削除されたオブジェクトthisと非静的メンバーを使用しないでください。

 

もう一つの方法は、

~Thread(); 

 

デストラクタを呼び出すことです。しかし、あなたがデストラクタを呼び出す必要がありますか、なぜ質問は、です!論理的ではありません。プライベートメソッドでリソースを管理するコードを記述して呼び出すことができます。

+4

スレッドがスタック上にあっても? –

+1

+1、delete文の後に 'this'や非静的なメンバ変数を使わないようにしたいかもしれません。 –

+0

@CommanderCorianderSalamander:この問題は、デストラクタを明示的に呼び出さなければならないことを意味します。つまり、オブジェクトが有効範囲外になるため呼び出されません。 – MSalters

2

あなたはこの構文を使用することができます:

~Thread(); 

をしかし、あなたが本当にC++のこの機能を必要とする場合、私は疑問です。あなたのクラスをよりよくデザインしてください。

デストラクタを明示的に呼び出すための1つの正当なケースは、オブジェクトを削除するためにdelete演算子を使用できないカスタムメモリマネージャです。

+1

正しい構文、固いアドバイス。 あなたはそれほどごくまれにそのような自分自身の破壊を始めたいと思っています。それは、ほとんどの場合、間違ったことを望んでいる人たちです。 – RichardPlunkett

+1

@RichardPlunkettプレースメントの外に - 新しいオブジェクト管理、私は誰もがこれをしたい理由を考えるのは難しいです。 – WhozCraig

+0

@WhozCraigは同意します。 C++仕様§12.4.14では、「デストラクタの明示的な呼び出しはほとんど必要ありません。このような呼び出しの1つの使用は、配置オプションで新しい式を使用して特定のアドレスに配置されたオブジェクトに対してです。専用のハードウェアリソースに対処し、メモリ管理機能を作成する必要があります。 –

0

デストラクタをクラスコード内から呼び出すのは悪い習慣だと思います。 デストラクタでも行われているクリーンアップを行う必要がある場合は、クリーンアップ()関数を使用してその作業をカプセル化し、その関数をstopから、そして必要に応じてデストラクタから呼び出さなければなりません。

明らかに、このような解決策では、不要な作業や複数のリソースの解放を避けるために、オブジェクトがすでにクリーンアップされているかどうかをオブジェクトに知らせる必要があります。

スレッドを管理するメカニズムがある場合、なぜ停止機能からスレッドを削除したいのか分かりません - スレッドではなく外部からスレッドを割り当て/割り当て解除する必要があります停止時に自身のメモリーを割り振り解除します。 (スレッドは上記のようにクリーンアップを実行する必要がありますが、独自のデストラクタを呼び出す必要はありません)

+0

'cleanup()'がデストラクタとまったく同じでも?例えば私は、クリーンアップするいくつかのミューテックス、デストラクタ(と 'クリーンアップ()、同じ)、ちょうど現在のスレッドによって所有されているミューテックスを検出してロックを解除しようとする。ある時点で私は 'cleanup()'をしたいと思っていますが、クラスインスタンスが破棄されたときには、mutexのロックを解除します。したがって、それらはまったく同じコードを共有します。 –

0

いいえこれを行わないでください。

他のオブジェクトがスレッドを所有している。

stop()に電話すると、スレッドはその所有者に削除準備ができたことを通知する必要があります(完了する前に所有者が削除されないように自分自身をロックしてください)。その後、オブジェクトの所有者に適切なクリーンアップをさせてください(うまくいけば近い将来)。

+0

downvoterは私たちの残りの部分を教えてくれますか?これは、私のための完全に合理的なアドバイスのように思えます。これは、大多数のケースでより良いコードにつながる可能性があります。 –

0

メンバー関数内からdelete thisを呼び出すのではなく、オブジェクトを削除する準備ができていることを所有者に通知することはありません。

私はワーカーを作成するサービスを持っていますが、作成後は気にしません。労働者階級の中から次に

Worker* w; 
[...] 
while (1) { 
    [...] 
    w = new Worker(); 
    [...] 
} 

:労働者クラスの外で何があるよう

void Worker::doWork() { 
    [...] 
    [...] 
    delete this; 
} 

すべてのサービスクラスは、新しい労働者を作るではないんサービスクラス内から

新しいワーカーが作成されるたびに破棄されるポインタw以外のワーカーへの参照。

この場合、私はそれはそれは限りdelete this;doWork()の最後の文で、何のsuccesiveメンバーコールがdoWork()後に存在しないとして(行うにはより多くの仕事を持っていないときに、作業者の内部でdelete thisを呼び出すために理にかなっていると思います。

作成した作業者のすべてのインスタンスを保存していた場合は、これ以上は当てはまりません。

関連する問題