次のような同期プリミティブの所有権を表すクラスを作成することを考えています。
class CCriticalSectionLock
{
public:
CCriticalSectionLock( CCriticalSection &cs ) : cs( cs )
{ cs.Enter(); }
~CCriticalSectionLock()
{ cs.Leave(); }
private:
CCriticalSection &cs;
};
これは、関数中に所有権を取得し、複数の出口点または例外がある場合でも所有権を解放できるようにするための良い方法のように見えます。ただし、コンパイラがさまざまなものを評価する正確なタイミングについて、いくつかの微妙な問題が発生します。次の使用を検討してください。
int MyMethod( void )
{
not_locked(); // do something not under lock
CCriticalSectionLock myLock( someCriticalSection );
locked(); // do something under lock
return ...; // some expression
}
私の知る限り、C++ のライフタイム ルールは、ロックが取得される前not_locked()
に呼び出されること、およびロックが保持されている間に呼び出されることを保証します。locked()
ただし、ロック デストラクタが呼び出されるポイントに関して、返される式がいつ評価されるかについては、はっきりしていません。デストラクタの前に式が評価されることが保証されていますか? 私はそう思いますが、100% 確信があるわけではありません。そうでなければ、非常に微妙で、断続的で、見つけにくいバグにつながる可能性があります。