zoukankan      html  css  js  c++  java
  • 构造/析构/赋值运算

    构造/析构/复制运算

    05.了解C++默默编写并调用哪些函数

    • 如果你没有声明,编译器就会为他声明一个copy构造函数,一个copy assiggnment操作符和一个析构函数,如果没有构造函数,编译器会为你声明一个default构造函数.所有这些都是public且inline.
    class Empty {};
    
    // 就像写下这样的代码
    class Empty{
    public:
        Empty() {...}                             // default 构造函数
        Empty(const Empty& rhs) {...}        // copy构造函数
        ~Empty() {...}                 // 析构函数,是否该是virtual稍后说明
        
        Empty& operator=(const Empty& rhs) {...} // copy assignment 操作符
    };
    
    // 编译器餐厨的析构函数是一个non-virtual,除非这个class的base class自身声明有virtual析构函数.
    // 这种情况下这个函数的虚属性;virtualness;主要来自base class.
    
    • **注意: ** 编译器可以暗自为class 创建default构造函数,copy构造函数,copy assignment操作符,以及析构函数.

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

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

      class HomeForSale{
      public:
          ...
      private:
          ...
          HomeForSale(const HomeForSale&);             // 只是声明
          HomeForSale& operator=(const HomeForSale&);
      };
      
      // 没有写函数参数的名称,参数名称并非必要,这个函数毕竟不会被实现出来,也很少被使用,没必要指定参数名称.
      
    • 将连接期错误移至编译期是可能的(而且是好事,毕竟越早侦测出错误越好),只要将copy构造函数和copy assignment 操作符声明为private就可以办到,但不是在HomeForSale自身,而是在一个专门为了阻止coping动作而设计的base class内.

      class Uncopyable{
      protected:                    // 允许derived对象构造和析构
          Uncopyable() {}
          ~Uncopyable() {}
      private:               // 阻止copying 
          Uncopyable(const Uncopyable&);
          Uncopyable& operator=(const Uncopyable&);
      };
      
      // 为求阻止HomeForSale对象被拷贝,我们唯一需要做的就是Uncopyable:
      class HomeForSale: private Uncopyable{
          ...
      };
      
      // 只要任何人--甚至是member函数或friend函数--尝试拷贝HomeForSale对象,编译器便试着生成一个copy构造函数和一个copy assignment操作符.这些函数的"编译器生成版"会尝试调用其base class的对应兄弟,那些调用会被编译器拒绝,应为其base class 的拷贝函数是private.
      

    07.为多态基类声明virtual析构函数

    • polymorphic(带多态性质的)base classes 应该声明一个virtual析构函数.如果class 带有任何virtual函数,它就应该拥有一个virtual析构函数.
    • Classes的设计目的如果不是作为base classes使用,或不是为了具备多态性(polymorphically),就不该声明virtual析构函数.

    08.别让异常逃离析构函数

    • 析构函数绝对不要吐出异常.如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下他们(不传播)或结束程序.
    • 如果客户需要对某个函数运行期间抛出的异常做出反应,那么class 应该提供一个普通函数(而非在析构函数中)执行该操作.

    09.绝不在构造和析构过程中调用virtual函数

    • 在构造和析构期间不要调用virtual函数,因为这类调用从不下降至derived class(比起当前执行构造函数和析构函数的那层).

    10. 令operator=返回一个reference to * this

    • 令赋值(assignment)操作符返回一个reference to *this

    11.在operator=中处理"自我赋值"

    • 确保当对象自我赋值时operator=有良好行为.其中技术包括比较"来源对象"和"目标对象"的地址,精心周到的语句顺序,以及copy-and-swap.
    • 确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为任然正确.

    12.复制对象时勿忘其每一个成分

    • copying 函数应该确保复制"对象内的所有成员变量"及所有base class成分.

    • 不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个函数中,并由两个copying函数共同调用.

  • 相关阅读:
    JVM(二)JVM内存布局
    JVM(一) OpenJDK1.8源码在Ubuntu16.04下的编译
    阿里面试
    npm run dev/npm run start报错
    vue 项目报错 You may use special comments to disable some warnings.
    ES6模块化
    jQuery中的动画
    jsonp的封装
    ajax中get,post,以及二合一的封装
    小案例之刮奖
  • 原文地址:https://www.cnblogs.com/o-v-o/p/10161073.html
Copyright © 2011-2022 走看看