禁用复制构造函数

Hum*_*ger 156 c++ copy-constructor

我有一节课:

class SymbolIndexer {
protected:
  SymbolIndexer ( ) { }

public:
  static inline SymbolIndexer & GetUniqueInstance ( ) 
  { 
    static SymbolIndexer uniqueinstance_ ;
    return uniqueinstance_ ; 
  }
};
Run Code Online (Sandbox Code Playgroud)

我该如何修改它以禁用如下代码:

SymbolIndexer symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );
Run Code Online (Sandbox Code Playgroud)

并且只允许以下代码:

SymbolIndexer & ref_symbol_indexer_ = SymbolIndexer::GetUniqueInstance ( );
Run Code Online (Sandbox Code Playgroud)

R. *_*des 261

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

private:
    SymbolIndexer(const SymbolIndexer&);
Run Code Online (Sandbox Code Playgroud)

或者在C++ 11中,明确禁止它:

SymbolIndexer(const SymbolIndexer&) = delete;
Run Code Online (Sandbox Code Playgroud)

  • 关于`delete`关键字,我想添加以下内容.在设计新类时我目前的习惯是立即"删除"复制构造函数和赋值运算符.我发现,根据上下文,它们几乎是不必要的,删除它们可以防止出现意外行为.如果出现可能需要复制ctor的情况,请确定是否可以使用移动语义来完成.如果这是不合需要的,请为(!)copy ctor和赋值运算符提供实现.这是否是一个好方法,我将留给读者. (37认同)

fir*_*iku 27

如果你不介意多重继承(毕竟它不是那么糟糕),你可以用私有拷贝构造函数和赋值运算符编写简单的类,并另外将它子类化:

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

class SymbolIndexer: public Indexer, public NonAssignable {
};
Run Code Online (Sandbox Code Playgroud)

对于GCC,这会给出以下错误消息:

test.h: In copy constructor ‘SymbolIndexer::SymbolIndexer(const SymbolIndexer&)’:
test.h: error: ‘NonAssignable::NonAssignable(const NonAssignable&)’ is private
Run Code Online (Sandbox Code Playgroud)

不过,我不太确定这可以在每个编译器中工作.有一个相关的问题,但还没有回答.

UPD:

在C++ 11中,您还可以NonAssignable按如下方式编写类:

class NonAssignable {
public:
    NonAssignable(NonAssignable const&) = delete;
    NonAssignable& operator=(NonAssignable const&) = delete;
    NonAssignable() {}
};
Run Code Online (Sandbox Code Playgroud)

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:
Run Code Online (Sandbox Code Playgroud)

UPD:

Boost已经有一个类只是为了同一个目的,我想它甚至以类似的方式实现.该类被调用,boost::noncopyable并且用于以下内容:

#include <boost/core/noncopyable.hpp>

class SymbolIndexer: public Indexer, private boost::noncopyable {
};
Run Code Online (Sandbox Code Playgroud)

如果您的项目政策允许,我建议坚持使用Boost的解决方案.有关更多信息,另请参阅另一个boost::noncopyable相关问题.

  • @Troyseph:`const Class&`和`Class const&`非常相似.对于指针,您甚至可以使用`Class const*const`类型. (3认同)