zoukankan      html  css  js  c++  java
  • C++进阶--编译器自动生成的类函数

    //############################################################################
    /*    在C++ 03标准下
    在没有显式定义的情况加,编译器会自动生成以下4个函数
    1. 拷贝构造函数
    2. 拷贝赋值运算符
    3. 析构函数
    4. 默认构造函数(只有当没有声明任何构造函数的时候)
    */
    
    class dog {};
    
    /* 这个看似空的类,其实等效于下面这个类 */
    
    class dog {
    	public:
    		dog(const dog& rhs) {...};   // 逐成员的初始化
    
    		dog& operator=(const dog& rhs) {...}; // 逐成员的拷贝
    
    		dog() {...};  // 1. 调用基类的默认构造函数,按照他们的继承时声明的顺序
    		              // 2. 调用数据成员的默认构造函数,按照他们在类中声明的顺序
    
    		~dog() {...}; // 1. 调用基类的析构函数
    		              // 2. 调用数据成员的析构函数
    /*
    注意:
    1. 这些函数是公有且内联的public and inline.
    2. 只有当需要的时候才会生成,即如果没用到不会生成
    3. 如果某个函数不满足生成的必要条件,则不会生成该函数
    */
    
    
    /*  例子:  编译器是否会自动生成这些函数
      1. Copy constructor.   - no 因为没有用到拷贝构造
      2. Copy Assignment Operator. - yes 
      3. Destructor.  - no 用户自己已定义
      4. Default constructor - no 已经有用户定义的构造函数
    */
    class dog {
    	public:
    		string& m_name;   // 如果这里改成引用,则此程序没法编译通过,因为该引用成员不允许拷贝
    
    		dog(string name = "Bob") {m_name = name; cout << name << " is born." << endl;}
    		~dog() { cout<< m_name << " is destroyed.
    " << endl; }
    };
    
    int main() {
      dog dog1("Henry");
      dog dog2;
      dog2 = dog1;  //需要逐成员拷贝
    }
    
    输出:
    Henry is born.
    Bob is born.
    Henry is distroied.
    Henry is distroied.
    
    注意:
     当拷贝赋值运算符是非法的时候,编译器会拒绝生成它
     1. 引用成员数据
     2. 常量成员数据
    这样的类不能用在STL容器中,因为容器的元素必须
    能够拷贝构造和拷贝赋值
    */
    
    /* 例子 2: */
    class collar {
    	public:
    	collar() { std::cout <<  " collar is born.
    "; }
    };
    
    class dog {
    	collar m_collar;
    	string& m_name;
    };
    
    int main() {
    	dog dog1;
    }
    
    
    输出:
    main.cc:13: error: no matching function for call to `dog::dog()'
    main.cc:8: note: candidates are: dog::dog(const dog&)
    
    // 没法编译通过,因为编译器会尝试为dog类生成默认构造函数,
    // 需要先生成数据成员collar m_collar的默认构造函数,而collar类已经有一个构造函数
    
    // 如果在dog类中增加如下成员:
    // string& m_name; 
    // Result: not compilable because age is not initialized.
    // 生成的默认构造函数不会进行初始化,引用必须初始化
    
    
    /* C++ 11 Update: */
    class dog {
       public:
          dog() = default;  //C++ 11提供了定义默认构造函数的方法
          dog(string name) {...};  //即使已经定义了其他构造函数,还可以定义默认构造函数
    }
    
  • 相关阅读:
    LCA最近公共祖先Tarjan(离线)
    51nod 1135 原根
    51nod 1134最长递增子序列
    51nod 1130 斯特林公式
    51nod 1186 Miller-Rabin素数测试
    51Nod 1257 背包问题 V3
    另类求组合数
    Gym
    msp430项目编程45
    msp430项目编程44
  • 原文地址:https://www.cnblogs.com/logchen/p/10165070.html
Copyright © 2011-2022 走看看