Effective C++条項14

2175 ワード

リソースマネージャでのcopying動作に注意
前節では、リソースの管理について説明しましたが、shared_に依存できない場合があります.ptrまたはauto_ptrなので、自分のリソースを管理するために自分でリソース管理クラスを構築する必要があります.
たとえば、Mutexロックを管理するクラスを作成し、関数処理タイプがMutexの反発オブジェクトを使用します.
class Lock{
public:
    explicit Lock(Mutex* mu):mutexPtr(mu)
    {
        lock(mutexPtr);
    }
    ~Lock()
    {
        unlock(mutexPtr);
    }
private:
    Mutex* mutexPtr;
};


void lock(Mutex* mu);//  
void unlock(Mutex* mu);//  

Mutex m;//     
……
{
    Lock(&m);
    ……
}

以上のコードはリソースの解放を完了することができ、ここでの解放はmutexにとって本当の意味は破壊ではなくロックを解除することである.
しかしながら、ロックm 2(m 1)の実行など、上記のコードには問題がある.この言葉の時、私たちはどのように直面する必要がありますか?2つのオブジェクトがインタラクティブにmutexを操作しているのではないでしょうか.このようにするのは絶対にだめで、私たちはいつm 2とm 1が分析されるかを確定することができなくて、いったん分析されるとmutexがロックを解除して、mutexがロックを解除すると別のプロセスに呼び出されて、プログラムは巨大な混乱が現れます!
上記の問題を解決するには、一般的に以下の方法があります.
1、複製を禁止する多くの場合、複製RAIIオブジェクトは合理的ではない.たとえばロッククラスは,このときコピーを禁止することができ,coping関数をプライベートにするだけで,条項6に述べる.
2、管理資源に対して参照計数法を使用する.真似shared_ptr
3、下のリソースをコピーします.ここでコピーしたら
4、下位資源の所有権を移転する.真似auto_ptr.
著者らは、第2の方法の具体的な操作を以下のように挙げた.
class Lock:private Uncopyable{
public:
    explicit Lock(Mutex* mu):mutexPtr(mu,unlock)//   Mutex   ,unlock     
    {
        lock(mutexPtr);
    }
private:
    shared_prt<Mutex> mutexPtr;
};

上記ロッククラスでリファレンスカウンタを使用する場合は、mutexPrtをタイプに変更してMutex*からsharedに変更するだけです.でもshared_ptrのデフォルトは、参照カウントが0の場合、マルチポインタオブジェクトを削除することです.これは私たちが望んでいるものではありません.unlock関数を呼び出すことを望んでいます.幸いなことにshared_ptrでは、リファレンスカウントが0のときに呼び出される関数である「削除器」を指定できます.