編集: j_random_hackerが指摘しているように、ロックを解除するために、ユーザーに名前付きオブジェクトの宣言を強制することができます。
ただし、クラスで一時的な作成が何らかの理由で禁止されている場合でも、ユーザーは同様の間違いを犯す可能性があります。
// take out a lock:
if (m_multiThreaded)
{
CSingleLock c(&m_criticalSection, TRUE);
}
// do other stuff, assuming lock is held
最終的に、ユーザーは自分が書いたコード行の影響を理解する必要があります。この場合、オブジェクトを作成していることを知っている必要があり、オブジェクトがどのくらい続くかを知っている必要があります。
もう1つの考えられる間違い:
CSingleLock *c = new CSingleLock(&m_criticalSection, TRUE);
// do other stuff, don't call delete on c...
「クラスのユーザーがヒープに割り当てるのを防ぐ方法はありますか?」と尋ねるのはどれですか。答えは同じだろう。
C ++ 0xでは、ラムダを使用して、これをすべて行う別の方法があります。関数を定義します。
template <class TLock, class TLockedOperation>
void WithLock(TLock *lock, const TLockedOperation &op)
{
CSingleLock c(lock, TRUE);
op();
}
この関数は、CSingleLockの正しい使用法をキャプチャします。次に、ユーザーにこれを実行させます。
WithLock(&m_criticalSection,
[&] {
// do stuff, lock is held in this context.
});
これは、ユーザーが台無しにするのがはるかに困難です。構文は最初は奇妙に見えますが、[&]の後にコードブロックが続くということは、「引数をとらない関数を定義することを意味します。名前で何かを参照し、それが外部の何かの名前である場合(たとえば、含まれているローカル変数)関数)非定数参照でアクセスさせて、変更できるようにします。)