在C++类中,编译器能够暗自为class建立default构造函数、copy构造函数、copy assignment操做符,以及析构函数。注意,这些编译器产生出来的函数都是public的,为了阻止这些函数被建立出来,咱们能够把它们声明为private,这样就阻止了编译器暗自建立其对应版本函数。c++
class Node { public: Node(int _data = 0) : data(_data) {} int get() const { return data; } void set(int _data) { data = _data; } private: Node(const Node &); Node &operator=(const Node &); int data; };
在上面的class定义中,当程序企图拷贝Node对象时,编译器就会阻止该操做。这样的话,只要将copy构造函数和copy assign操做符声明为private就能够了,还有另一种方式,咱们能够专门定义一个阻止copying动做的base class。这个base class以下所示:函数
class Uncopyable { protected: Uncopyable() {} // 容许derived对象构造和析构 ~Uncopyable() {} private: Uncopyable(const Uncopyable &); // 阻止copying Uncopyable &operator=(const Uncopyable &); }; class Node : private Uncopyable { public: Node(int _data = 0) : data(_data) {} int get() const { return data; } void set(int _data) { data = _data; } private: int data; };
这样的话,在程序中,甚至在member函数或friend函数中,尝试拷贝Node对象,编译器就会试着生成一个copy构造函数或copy assign操做符,这些函数的“默认版本”会尝试调用其base class的对应函数,可是这些调用会被阻止,由于它们是private的,即阻止了该类对象的copy操做。学习
参考资料:spa
【1】 《Effective C++ 第3版》 条款6指针
而经过阅读开源代码学习能够使用宏定义来禁止class的拷贝构造函数和赋值构造函数(如下代码源于Apollo/modules/common/macro.h)code
宏定义 DISALLOW_COPY_AND_ASSIGN:对象
#define DISALLOW_COPY_AND_ASSIGN(classname) \ private: \ classname(const classname &); \ classname &operator=(const classname &);
用于在C++中禁止class的拷贝构造函数和赋值构造函数,良好的c++代码应该主动管理这2个操做符。get
在caffe、cartographer和Apollo或者其余的著名库中均有相似的操做。编译器
宏定义 DISALLOW_IMPLICIT_CONSTRUCTORS:编译
#define DISALLOW_IMPLICIT_CONSTRUCTORS(classname) \ private: \ classname(); \ DISALLOW_COPY_AND_ASSIGN(classname);
禁止class的无参构造函数。
宏定义 DECLARE_SINGLETON:
#define DECLARE_SINGLETON(classname) \ public: \ static classname *instance() { \ static classname instance; \ return &instance; \ } \ DISALLOW_IMPLICIT_CONSTRUCTORS(classname) \ private:
单例类定义,instance() 返回指向同一个class对象的指针。禁止拷贝/赋值运算符。