禁用复制构造函数

我有一门课:

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 ( );
169106 次浏览

SymbolIndexer( const SymbolIndexer& )设为私有。如果你给一个引用赋值,你就不是在复制。

你可以将复制构造函数设为私有,不提供任何实现:

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

不过,我不太确定这是否适用于每个编译器。有一个相关的问题,但还没有答案。

乌利希期刊指南:

在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:

乌利希期刊指南:

Boost已经有一个类是为了同样的目的,我猜它甚至是以类似的方式实现的。这个类被称为boost::noncopyable,它的用途如下:

#include <boost/core/noncopyable.hpp>


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

如果你的项目策略允许的话,我建议你坚持使用Boost的解决方案。更多信息请参见另一个boost::noncopyable-related问题