オブジェクトが相互に呼び出し、しばらくすると、呼び出されたオブジェクトが開始オブジェクトをコールバックする OO 設計を想定します (呼び出しとコールバック)。通常のプログラムの終了時に、デストラクタが呼び出されている間、システム タイマーが呼び出されず、オブジェクトがコールバックを開始しないという約束はありますか?
4 に答える
いいえ、そのような保証はありません。
オブジェクトの使用が完了するまで、オブジェクトが破棄されないようにコードを記述する必要があります。
これらの種類の呼び出しを処理するための非常に優れたライブラリがあり、もちろんそれは Boost です。
マルチスレッドアプリケーションでも正確性が保証されている Boost.Signals2 をご覧ください:)
特にboost::trackable
クラスの使用に注意してください。オブジェクトの破棄により、呼び出しが発生する前に自動的に無効になります。
注: Boost.Signals (その祖先) はほとんど同じ機能を持っていますが、スレッドセーフではありません
- boostのweak_ptrは、一般的にコールバックから破壊されたオブジェクトにアクセスすることを回避するのに役立ちます。したがって、おそらく終了時にもそうです。これを使用する場合、コールバックする必要があるすべてのオブジェクトには、shared_ptrが必要です。
- 関数/コールバックを呼び出すタイマーは通常、ハイエンドライブラリであるため、stopAllTimers()機能をサポートしているかどうかによって異なります。ライブラリを制御できる場合は、実装はそれほど難しくありませんが、いつトリガーするかを知る必要があります。
いいえ、約束はありません。
これを処理するには、次の 2 つの方法があります。
オブジェクトが破棄時に呼び出すことができる登録解除関数を用意します。これにより、終了後にコールバックが呼び出されないことが保証されます
CancelAllCallbacks()
。強い参照が正常に取得された場合にのみコールバックを呼び出すために、既に述べた weak_ptr などの弱い参照メカニズムを用意します。
通常、コールバックを非同期にスケジュールまたは呼び出すことができない限り、最初のオプションで十分です。その場合、すでに呼び出されるようにスケジュールされているコールバック、または実際に現在呼び出されているコールバックを同期的に防ぐ方法はありません (または現在)別のスレッドで。