2012-02-28 17 views
3

私のクラスのデータ構造へのアクセスを保護する必要があります。私はmutexを持つことができないので(私はそれをコピーできないので)、私はshared_ptrを持って、mutexをそこに保つことを考えています。ここに私の考えのサンプルコードは次のとおりです。boost :: shared_ptr boost :: mutexとコピーコンストラクタ

class Sample { 
    typedef boost::lock_guard<boost::mutex> AcquireLock; 
    boost::shared_ptr<boost::mutex> mutt; 

public: 
    Sample() : mutt(new boost::mutex) {} 

    void Method() 
    { 
     AcquireLock lock(*mutt); 

     //do some work here 
    } 
}; 

私は、次の質問を持っている:

  • shared_ptrのを経由して、クラスのメンバとして(ミューテックスをそのように使うのは悪い習慣です)?
  • shared_ptr経由でヒープにメモリが割り当てられているため、このクラスのコピーコンストラクタを用意する必要がありますか?

編集:たぶん私は、もう少し詳細を与える必要があります。 私は一度だけ、このオブジェクトを作成するとstd ::ベクトルに保存します。私はそれをコピーする必要はなく、ベクトルがコピーを作成する必要がある場合、コピーごとに異なるミューテックスを持つことは望ましくありません。だから私はコピーコンストラクタが私のために働くと思うのです。

答えて

1

Sampleオブジェクトのコピーを作成すると、コンパイラーによって自動的に生成されたコピーコンストラクターが呼び出されるか、明示的に書き込まれたコピーコンストラクターが呼び出されます。

サンプルオブジェクトのコピーを許可することは、何をしようとしているかによって異なります。 コピーを許可するのが理にかなっていない場合は、オブジェクトをコピーできないようにします。コピーコンストラクタのためのプライベートプロトタイプを与えることによって。

コピーを許可する場合は、各コピーに独自のミューテックスを含めるかどうかを決定し、コピーコンストラクタを適切に定義する必要があります。自動的に生成されるコピーコンストラクタは、浅いコピーのみを実行するので、すべてのコピーがミューテックスを共有します。

+0

私はオブジェクトをstd :: vectorに保存してそこから使用するのでコピーがあります。それ以外にはコピーを作成しないので、デフォルトのコピーコンストラクタが私のために働くと思います。私が迷っているのは、浅いコピーが参照カウントなどを混乱させ、将来問題を引き起こす場合です。 –

+1

ベクトルのSampleオブジェクトにshared_ptrを格納しないと、コピーされるSampleオブジェクトについて心配する必要はありません –

2

このアプローチはきわめて有効で正当なものですが、クラスが進化するにつれて、同じテクニックをいくつかのクラスメンバーに適用することができます。ですから、私はpImplイディオムを利用することをお勧めします:

// in hpp: 
class Sample 
{ 
    Impl(); 
private: 
    struct Impl; 
    // compiler generated copy-constructor will copy only this shared_ptr 
    shared_ptr<void> pImpl_; 
}; 

// in cpp: 
struct Sample::Impl 
{ 
    mutex mut_; 
    // put here whatever members you need, extend Impl without affecting the Sample interface 
}; 

Impl::Impl() : pImpl_(new Impl) 
{} 
関連する問題