22

スコープに基づいてミューテックスのロック/ロック解除を制御するコードがあります。

void PerformLogin()
{
    ScopeLock < Lock > LoginLock( &m_LoginLock );

    doLoginCommand();

    ScopeLock < SharedMemoryBase > MemoryLock( &m_SharedMemory );

    doStoreLogin();

    ...
}

MemoryLockがの前に破壊されることを保証できますLoginLockか?

4

5 に答える 5

40

はい、そうです。特定のスコープでは、ローカル オブジェクトは構築された順序と逆の順序で破棄されます。

于 2009-08-07T16:54:47.837 に答える
11

はい、デストラクタは構築の逆の順序で呼び出されます。

于 2009-08-07T16:54:52.983 に答える
11

ニールの答えに追加します。

逆の場合、つまり、スタック宣言された変数のデストラクタの順序を予測できなかった場合を考えてみてください。これにより、依存する値の型をスタックで使用することがほぼ不可能になります。検討

void Foo() {
  Type1 t1;
  Type2 t2(&t1);
  ...
}

C++ がデストラクタの順序付けを保証していない場合、t2 のデストラクタが実行される前に t1 が破棄される可能性があるため、このような単純なコードは非常に安全ではありません。したがって、t2 のデストラクタが有効な t1 値で実行されたことを保証できませんでした。

于 2009-08-07T16:58:58.687 に答える
3

質問はすでに回答されていますが、私は通常、次のようなものを書く習慣があることを付け加えておきます。

void PerformLogin()
{
    ScopeLock < Lock > LoginLock( &m_LoginLock );
    doLoginCommand();

    {
        ScopeLock < SharedMemoryBase > MemoryLock( &m_SharedMemory );
        doStoreLogin();
        ...
    }
}

これで意図がより明確になると思います(*)。コードが実際に特定の順序に依存している場合、これは関連する可能性があります。これにより、誰かが誤って順序を変更する可能性が低くなり、見つけにくいバグが発生することがわかりました. (もちろん、それは問題ではありません。私たち全員がテストを実施しているので、そうではありませんか?)

私もいつも冗長な括弧を のように書いています  (a && b) || c  が、これもよく似ていると思います。

(*): もちろん、コメントを使用することもできます。

于 2009-08-07T21:13:40.653 に答える
0

はい、デストラクタはコンストラクタの逆です。デストラクタは不要になったオブジェクトを削除するために使用され、コンストラクタはオブジェクトを作成するために使用されるためです。

于 2011-01-14T08:39:28.840 に答える