我有一个班级:
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 ( );
答案 0 :(得分:249)
您可以将复制构造函数设为私有,并且不提供任何实现:
private:
SymbolIndexer(const SymbolIndexer&);
或者在C ++ 11中,明确禁止它:
SymbolIndexer(const SymbolIndexer&) = delete;
答案 1 :(得分:26)
如果你不介意多重继承(毕竟它并不是那么糟糕),你可以用私有拷贝构造函数和赋值运算符编写简单的类,并附加子类:
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
但是,我不太确定这可以在每个编译器中工作。有一个related question,但尚无答案。
<强> 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
-related question。
答案 2 :(得分:4)
将SymbolIndexer( const SymbolIndexer& )
设为私有。如果您要分配参考,则不要复制。
答案 3 :(得分:-1)
了解引用与指针的 C++ 开发人员可能很想拥有
class MyClass {
SomeClass acc;
public:
MyClass() : acc() {}
SomeClass &GetAccess( return acc; );
};
作为一种方便的方法:
someblock->{
MyClass inst;
auto acc = inst.GetAccess();
acc.SomeFunction();
}
这会在 SomeClass 内部产生双重释放的问题,因为默认情况下你最终会得到一个副本......