web-dev-qa-db-ja.com

コピーコンストラクターを無効にする

私にはクラスがあります:

class SymbolIndexer {
protected:
  SymbolIndexer ( ) { }

public:
  static inline SymbolIndexer & GetUniqueInstance ( ) 
  { 
    static SymbolIndexer uniqueinstance_ ;
    return uniqueinstance_ ; 
  }
};

次のようなコードを無効にするには、どのように変更する必要がありますか?

SymbolIndexer symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );

次のようなコードのみを許可します。

SymbolIndexer & ref_symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );
151
Humble Debugger

コピーコンストラクタをプライベートにし、実装を提供しないことができます。

private:
    SymbolIndexer(const SymbolIndexer&);

または、C++ 11では、明示的に禁止します。

SymbolIndexer(const SymbolIndexer&) = delete;
254

多重継承を気にしない場合(結局悪いことではありません)、プライベートコピーコンストラクターと代入演算子を使用して単純なクラスを作成し、さらにサブクラス化することができます。

class NonAssignable {
private:
    NonAssignable(NonAssignable const&);
    NonAssignable& operator=(NonAssignable const&);
public:
    NonAssignable() {}
};

class SymbolIndexer: public Indexer, public NonAssignable {
};

GCCの場合、次のエラーメッセージが表示されます。

test.h: In copy constructor ‘SymbolIndexer::SymbolIndexer(const SymbolIndexer&)’:
test.h: error: ‘NonAssignable::NonAssignable(const NonAssignable&)’ is private

ただし、これがすべてのコンパイラで機能するかどうかはわかりません。 関連する質問 がありますが、まだ回答はありません。

UPD:

C++ 11では、次のようにNonAssignableクラスを記述することもできます。

class NonAssignable {
public:
    NonAssignable(NonAssignable const&) = delete;
    NonAssignable& operator=(NonAssignable const&) = delete;
    NonAssignable() {}
};

deleteキーワードは、メンバーがデフォルトで構築されるのを防ぐため、派生クラスのデフォルトで構築されたメンバーでそれ以上使用することはできません。割り当てようとすると、GCCで次のエラーが発生します。

test.cpp: error: use of deleted function
          ‘SymbolIndexer& SymbolIndexer::operator=(const SymbolIndexer&)’
test.cpp: note: ‘SymbolIndexer& SymbolIndexer::operator=(const SymbolIndexer&)’
          is implicitly deleted because the default definition would
          be ill-formed:

UPD:

Boostにはすでに同じ目的のためのクラスがありますが、同様の方法で実装されていると思います。クラスは boost::noncopyable と呼ばれ、次のように使用することを意図しています。

#include <boost/core/noncopyable.hpp>

class SymbolIndexer: public Indexer, private boost::noncopyable {
};

プロジェクトポリシーで許可されている場合は、Boostのソリューションに固執することをお勧めします。詳細については、別の boost::noncopyable関連の質問 も参照してください。

27
firegurafiku

SymbolIndexer( const SymbolIndexer& )をプライベートにします。参照に割り当てている場合、コピーしていません。

4
Aaron Klotz