• 条款6:不想使用编译器自动生成的函数,就要明确拒绝!


    每一个对象都是独一无二的,如果不想其被复制,我们就希望其复制以失败收场。
    如一座房屋出售HomeForSale类:

    1 HomeForSale h1;
    2 HomeForSale h2;
    3 HomeForSale h3(h1);//我们希望这俩语句以失败告终
    4 h1=h2;//

    通常情况下,我们使用某个功能时,调用相对应的函数即可,如果这个函数没有被定义,则编译器会提示错误。但是这一情况不适用复制构造函数和赋值构造函数。因为条款5已经指出,如果你不声明它们,而有人希望调用它们,编译器就会替你声明。
    这就不太好了,不管我们是否声明它们,我们定义的某个类还是支持这种copy行为,但是这是要明确禁止的!
    答案的关键是,编译器产出的所有函数都是public的,为阻止这些函数的出现,我们就要自行声明其为private,这样就阻止了编译器私自创建其专属版本。这样的话别人就不可以调用它们。
    一般而言这个做法不是绝对安全,因为成员函数和友函数可以调用已经声明为private的copy特性函数。
    将成员函数定义为private而不去实现它们,这一招被大家接受,在C++ iostream库中阻止copy行为。在ios_base,basic_ios,和sentry中,无论哪个,其复制构造函数和赋值构造函数都被声明为private而没有定义。
    但是这个错误出现在连接期,如果我们希望错误提示越早出现越好,那么将其提前到编译器无疑是最棒的。

     1 Uncopyable
     2 {
     3 public:
     4 
     5 protected:
     6 Uncopyable();
     7 ~Uncopyable();//基类的析构函数不一定非得是virtual
     8 
     9 private:
    10 Uncopyable(const Uncopyable&);
    11 Uncopyable& operator=(const Uncopyable&);
    12 };
    13 class HomeForSale:private Uncopyable
    14 {
    15 
    16 };

    如果基类(Uncopyable)有复制构造函数和赋值构造函数而且为private的。那么其子类(HomeForSale)的对象如果被copy,那么,编译器就会创建一个复制构造函数和赋值构造函数,而且还会尝试调用其父类版本(复制和赋值),这时,编译器会拒绝调用,因为父类的复制和赋值是private的。

  • 相关阅读:
    Linux命令之cat
    Linux命令之diff
    Linux查看内核信息或系统信息
    Linux命令之touch
    linux脚本:shell, 判断输入参数的个数(命令行)
    c++中try catch的用法
    linux命令:ftp
    linux shell种类
    linux shell脚本:在脚本中实现读取键盘输入,根据输入判断下一步的分支
    c语言,gdb
  • 原文地址:https://www.cnblogs.com/Burgess-Fan/p/6890353.html
Copyright © 2020-2023  润新知