Отключить конструктор копирования
у меня есть класс :
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 ( );
3 ответов:
вы можете сделать конструктор копирования частным и не предоставлять реализацию:
private: SymbolIndexer(const SymbolIndexer&);или в C++11, явно запретить его:
SymbolIndexer(const SymbolIndexer&) = delete;
если вы не возражаете против множественного наследования (это не так уж плохо, в конце концов), вы можете написать простой класс с частным конструктором копирования и оператором присваивания и дополнительно подкласс:
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() {} };The
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вопрос для получения дополнительной информации.
Comments