显式屏蔽掉编译器自动生成的函数

  在编写一个新的class的时候,若有地方尝试调用到类的默认构造函数、copy构造函数、copy赋值函数,如果你没有声明上述函数,编译器会默认为你声明它。在有些情况下,这些class的每一个实例都是独一无二的,并不适合copy构造或者copy赋值,我们该如何去防止class的使用者对其进行这样的操作呢?

  答案的关键是,所有编译器产出的函数都是public的。为阻止这些函数被创建出来,我们可以自行创建出来,并声明为private的,这样class的使用者就无法调用它。一般而言,这个方法还是不够安全,因为这个class的member函数或者friend函数可以调用这些声明为private的copy构造/赋值函数。但是倘若我们声明这些函数并没有去实现它,则在链接的时候,如果有人调用了这些函数,则连接器会因为报找不到该函数的实现而报错:

class HomeForSale

{

public:

  ...

private:

  ...

  HomeForSale(const HomeForSale&);    // copy构造函数只有声明(这里没有函数参数的名称,因为不用实现它,所以也就名字也就没有了意义)

  HomeForSale& operator=(const HomeForSale&);  // copy赋值函数只有声明 

  ...

};

  

  当有人尝试调用HomeForSale的copy构造/赋值函数时,链接器将会报错。但如果想让这个错误在编译时期就暴露出来,有没有方法呢?下面是一个解决方法:

  我们设计一个专门为了阻止copying动作而设计的base class,

class UnCopyable

{

protected:

  UnCopyable(){};      // 允许derived对象构造和析构

  ~UnCopyable(){};

private:

  UnCopyable(const UnCopyable&);      // 但阻止copying

  UnCopyable& operator=(const UnCopyable&);

};

  为阻止HomeForSale对象被拷贝,我们唯一需要做的就是集成UnCopyable:

class HomeForSale : private UnCopyable 

{

...

};

  只要任何人(甚至是member函数或者friend函数)尝试拷贝HomeForSale对象,编译器便试着生成一个copy构造函数和一个copy assignment操作符,而这些编译器生成版的函数便会尝试调用其base class的对应函数,那些调用将会被编译器拒绝,因为其base class将拷贝函数声明为private的!

 

  

 

  

 

posted @ 2017-08-02 15:36  opkyo  阅读(215)  评论(0)    收藏  举报