effective C++读书笔记--【条款06:若不想使用编译器自动生成的函数,就该明确拒绝】

蓝图

这条其实基本上就是针对copy构造函数和copy assignment操作符这两个函数的,为什么这么说呢,其他的函数,不想用的话,不要声明不要定义就完了,但是copy构造函数和copy assignment操作符不声明不定义的话编译器会自动整一套public的出来,所以这让人比较为难,作者给出了两个方案:

  • 声明为private,但是不予以定义;
  • 使用Uncopyable base class;

声明为private,不予以定义

这是一个一步步的逻辑

  1. 不想让编译器提供copy构造函数和copy assignment操作符,那么我们必须予以声明;
  2. 为了不让其他人调用copy构造函数和copy assignment操作符,将其声明为private;
  3. 为了防止member函数和friend函数调用copy构造函数和copy assignment操作符,不予以定义使得工程在链接阶段报错;
class TstCls {
public:
    ...
private:
    TstCls(const TstCls&);       //只有声明,不要定义
    TstCls& operator=(const TstCls&);
}

显然这里又应用到了【条款5】笔记中说到的只声明不定义的情况。总的来说,感觉这是一个不怎么地道的办法,总有一种野路子的味道。另外,把错误提示从链接阶段提前到编译阶段总是好的,因此,作者又提出了Uncopyable bass class方法。

Uncopyable base class

即然是担心private声明的函数被其他member函数或friend函数调用,那么干脆就定义一个没有其他member函数,也没有friend函数的base class,就像这样

class Uncopyable {
protected:
  Uncopyable(){}        //允许derived对象构造和析构
  ~Uncopyable(){}
private:
  Uncopyable(const Uncopyable&);          //但是阻止copying
  Uncopyable& operator=(const Uncopyable&);
};

然后假如我们的TstCls不想要copy构造函数和copy assignment操作符,直接继承上面这个Uncopyable类就可以了。

作者给出的示例是这样的:

class HomeForSale: private Uncopyable {
    ...        //class不再声明copy构造函数,也不再声明copy assign操作符,当然也不要定义
};

这样编译器在尝试生成这两个copy函数时会去试图调用Uncopyable的对应的copy函数,但是Uncopyable的copy函数都是private的不能被derived class调用,因此编译出错。

其他

作者两句话值得仔细品味:

1.Uncopyable class的运用颇为巧妙,不一定得以public继承它:那到底该用public继承还是private继承,有什么影响区别?

2.Uncopyable的析构函数不一定得是virtual:那到底该不该是virtual,有什么影响区别?

从【条款7】可以看到,只有准备用于base class的类的析构函数才得是virtual的,因为virtual函数存在的意义就是多态,都不打算做base class,多态也就无从谈起,此时莫说析构函数,任何成员函数都不应该是virtual的,避免无端增大class的size。Uncopyable类虽然也是被继承的,但是其并不会用于多态的目的,因此没有必要使得析构函数是virtual的;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值