条款06:若不想使用编译器自动生成的函数,就该明确拒绝

127 篇文章 7 订阅
39 篇文章 3 订阅

条款06:若不想使用编译器自动生成的函数,就该明确拒绝

Explicitly disallow the use of compiler-generated functions you do not want.

拒绝拷贝操作

首先,从一个例子入手:
对于一个房产中介,它所使用的中介软件需要一个class来描述待售房屋

class HomeForSale { ... };

对于这样的房产,HomeForSale对象产生一个副本没有任何道理,因此,任何想对该对象进行拷贝的动作都应该失败:

HomeForSale h1;
HomeForSale h2;
HomeForSale h3(h1); //试图拷贝h1-应该被拒绝
h1 = h2;            //试图拷贝h2-应该被拒绝

一般来说,如果我们不想使用某种函数,只要不去声明它就好。但是对于copy构造函数和copy assignment操作符却不行:因为如果我们不去声明它们,而又有其他人对其进行尝试调用,则编译器会自动声明它们!

对于这样的问题的关键点在于,所有的编译器产出的函数都是public的。因此,我们可以人为地将copy构造函数和copy assignment操作符声明为private
此时,这样的操作阻止了编译器暗自创建默认的版本,而且令这些函数为private,可以阻止其他人的调用。

但是,这种办法并不是最优解。因为member函数friend函数还是可以去调用这些private函数。因此,一个经常使用的讨巧办法则是:

  • 将成员函数声明为private而且故意不去实现它们

因此,对于上面的例子:

class HomeForSale {
public:
    ...
private:
    ...
    HomeForSale(const HomeForSale&);    //只有声明而没有定义
    HomeForSale& operator=(const HomeForSale&);

当我们有了上述的class定义,当有人企图拷贝HomeForSale对象时,编译器会阻止(因为private)。而如果有member函数或friend函数尝试这样做,也会出现连接错误(linkage error)

Uncopyable class

上面这种解决办法是可行的,将连接错误迁移至编译期,更高的侦测出错误,对程序是有好处的。
但是不应该在HomeForSale class内实现,而是应该定义在专门为了阻止copying动作而设计的base class内。

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

为了阻止HomeForSale对象被拷贝,只需要继承这个Uncopyable类即可:

class HomeForSale : private Uncopyable {
    ...    //此时,HomeForSale class内不再声明copy构造函数和copy assignment操作符
 };

为了驳回编译器自动(暗自)提供的机能,可以将相应的成员函数声明为private并且不予实现。使用像Uncopyable这样的base class也是一种做法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值