Ответ 1
Вы можете сделать конструктор копирования закрытым и не выполнять реализацию:
private:
SymbolIndexer(const SymbolIndexer& that);
Или в С++ 11 явно запретите это:
SymbolIndexer(const SymbolIndexer& that) = delete;
У меня есть класс:
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 ( );
Вы можете сделать конструктор копирования закрытым и не выполнять реализацию:
private:
SymbolIndexer(const SymbolIndexer& that);
Или в С++ 11 явно запретите это:
SymbolIndexer(const SymbolIndexer& that) = 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:
В С++ 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
вопросе.
Сделайте SymbolIndexer( const SymbolIndexer& )
приватным. Если вы назначаете ссылку, вы не копируете.