2009-06-19 10 views
3
Callback* p = new Callback; 
function(p); 

コールバックオブジェクトを削除したい場合は、その削除の方法と方法を教えてください。オブジェクトを自分自身で削除するのはいつですか?

早期に削除されると、セグメンテーションフォルトでコールバックが失敗することがあります。

+0

これはあなた次第です。 –

答えて

17

スマートポインタを使用するのが最適です。
ポインタをコールバックで初期化し、関数に渡します。関数や何らかの処理が実行されると、コールバックはスマートポインタによって自動的に削除されます。
良いスマートポインタの実装はboost::shared_ptr<>

+0

共有ポインタが必要な場合は、コンパイラが提供するtr1 :: shared_ptrの実装を使用します(モダンであると仮定します)。そうでなければ、オーバーヘッドなしでRAIIにboost :: scoped_ptrを使用します。 – Patrick

+0

この状況では、std :: auto_ptrはよりスマートなポインタです。次に、コールバックオブジェクトの所有権を関数に渡します。 –

+0

私たちは、このコールバックがどこに行くのか全く分かっていないので、これらのどちらも安全に提案できないと言っています。 – shoosh

1

コールバックが使用されたときの増分/減分カウントを持つことができます。使用されているときは、使用しなくなったときにカウントをインクリメントし、カウントダウンします。それが0または-1に達すると解放します。

1

コールバック(コールバックを実行しているコールバック)オブジェクトが適切な所有者(コールバックのライフタイムを決定します。具体的には、deleteを使用してコールバックオブジェクトを取り除くことができます。 auto_ptrなどで保持します)。その意味がそれ以上のコールバックがいつ必要になるかを判断できるようなものである場合に限り、その質問で提供されたそのような重要な情報からは分かりません。

はまたコールバックを作成します(そして、呼び出し元後援者への所有権を渡す)明示的にコールバックオブジェクトを削除するには、「呼び出し側で助っ人」を尋ねる(およびこれ以上のコールバックを実行しないようにするコードのための方法が必要な場合があります)、それ以上のコールバックがこれ以上必要ではないと判断したコードである場合。

その他の回答には、「誰がこれを所有しているか」に関する問題を解消するために、よりスマートなポインタが記載されています(ブーストのshared_ptr、手書きリファレンスカウントなど...) - これはC++それ以外の理由でガベージコレクションの言語が本当に必要ですが、メモリ使用量を完全に制御できるためC++を選択した場合、オブジェクトの所有権と生涯の問題を正しく判断することはできません(リソースを大幅に最適化できます)どのような種類の多かれ少なかれ自動化された "ガベージコレクション"と比較すると、それは唯一重要です。は、あなたのリソース使用量を厳密に制御する必要があります;-)。

1

特定のCallbackオブジェクトを使用する唯一の関数であり、このコードは常にCallbackオブジェクトが作成された順序で実行されると仮定すると、func()が呼び出された後に配置されます。このように、func()を編集する必要がある場合、コールバックオブジェクトがどこで削除されるか心配する必要はありません。関数の終了時にfunc()のポインタが存在しなくなったので、すべてのポインタが空になっていることを確認します。残っているのは、ポインタを参照しているポインタを削除することだけです。

C++のポインタについての私の理解に間違いがあり、私に間違った答えを与えた場合はお詫び申し上げますが、私は常にそれについて少し混乱していました。

3

コードは、FUNC後のコールバックポインタへの唯一の参照()が実行されるがありますを意味し、私はauto_ptrはで十分だろうと信じて、あなたがそれを置くように簡単です場合:

std::auto_ptr<Callback> p(new Callback); 
func(p.get()); 

これはまた、そのあるべき保証func()はメモリを解放する例外をスローします。あなたのコードは、あなたが書かれているものと同じくらい簡単です、そしてfunc()は直接いくつかの点でコールバックを呼び出した場合、これは十分なはず

+0

"func(p.get())"を意味しましたか? – bk1e

+0

はい、ありがとうございます。 –

+0

所有権を関数に渡していない場合。これは愚かです。通常のオブジェクトを作成し、ポインタを渡すだけです!コールバックp; func(&p); –

1

Callback p; 
func(&p); 

しかし、func()がへの参照やポインタを保存している場合他の場所でのコールバック、その参照の存続期間を追跡する必要があります。

関連する問題