C++ 空類,默認產生哪些成員函數


 默認構造函數、默認拷貝構造函數、默認析構函數、默認賦值運算符 這四個是我們通常大都知道的。但是除了這四個,還有兩個,那就是取址運算符和 取址運算符 const

即總共有六個函數

    一個示例如下:

   1: class Empty
   2:  
   3: {
   4:  
   5:   public:
   6:  
   7:       Empty(); // 缺省構造函數
   8:  
   9:       Empty( const Empty& ); // 拷貝構造函數
  10:  
  11:       ~Empty(); // 析構函數
  12:  
  13:        Empty& operator=( const Empty& ); // 賦值運算符
  14:  
  15:        Empty* operator&(); // 取址運算符
  16:  
  17:        const Empty* operator&() const; // 取址運算符 const
  18:  
  19: };

  但是,C++默認生成的函數,只有在被需要的時候,才會產生。即當我們定義一個類,而不創建類的對象時,就不會創建類的構造函數、析構函數等。

 

1.對於一個類X,如果一個構造函數的第一個參數是下列之一

    a) X&

    b) const X&

    c) volatile X&

    d) const volatile X&

    且沒有其他參數或其他參數都有默認值,那么這個函數是拷貝構造函數

    X::X(const X&); //是拷貝構造函數

    X::X(X&, int=1); //是拷貝構造函數

 

2.類中可以存在超過一個拷貝構造函數,

class X { 
public: 
      X(const X&); 
      X(X&);            // OK 
};

注意,如果一個類中只存在一個參數為X&的拷貝構造函數,那么就不能使用const X或volatile X的對象實行拷貝初始化。

class X { 
public: 
     X(); 
     X(X&); 
};

const X cx; 
        X x = cx;    // error

    如果一個類中沒有定義拷貝構造函數,那么編譯器會自動產生一個默認的拷貝構造函數。

    這個默認的參數可能為X::X(const X&)或X::X(X&),由編譯器根據上下文決定選擇哪一個。

 

測試代碼如下:

   1: #include <iostream>
   2: using namespace std;
   3:  
   4: class X {
   5:   public:
   6:     X() { cout << "X()" << endl;}
   7:     X(X& x, int a = 1) {cout << "X(X&)" << endl;}
   8:     X(const X& x) {cout << "const X(X&)" << endl;}
   9:     X(volatile X& x) {cout << "volatile X(X&)" << endl;}
  10: };
  11:  
  12: int main(int argc, char** argv) {
  13:   X x1;
  14:   X x2(x1);
  15:   const X x3;
  16:   X x4(x3);
  17:   volatile X x5;
  18:   X x6(x55;
  19:   return 0;                                                                                                               
  20: }

運行結果:

image

而如果注釋掉上面的8 和9行(即取消const 和volatile 拷貝構造函數),會編譯錯誤,如下:

image

    默認拷貝構造函數的行為如下:

    默認的拷貝構造函數執行的順序與其他用戶定義的構造函數相同,執行先父類后子類的構造。

    拷貝構造函數對類中每一個數據成員執行成員拷貝(memberwise Copy)的動作。

    a)如果數據成員為某一個類的實例,那么調用此類的拷貝構造函數。

    b)如果數據成員是一個數組,對數組的每一個執行按位拷貝。

    c)如果數據成員是一個數量,如int,double,那么調用系統內建的賦值運算符對其進行賦值。

    3. 拷貝構造函數不能由成員函數模版生成。

struct X


              template<typename T> 
              X( const T& );    // NOT copy ctor, T can't be X

       template<typename T> 
              perator=( const T& ); // NOT copy ass't, T can't be X 
        };

        原因很簡單,成員函數模版並不改變語言的規則,而語言的規則說,如果程序需要一個拷貝構造函數而你沒 
有聲明它,那么編譯器會為你自動生成一個。所以成員函數模版並不會阻止編譯器生成拷貝構造函數, 賦值運算 
符重載也遵循同樣的規則。(參見Effective C++ 3edition, Item45)

 

另外這些函數,只有在沒有時,才會默認生成。而如果提供了聲明,即使沒有實現,也不會生成默認的函數。

因此我們通常用的方法是將拷貝構造和賦值設置為private而不實現,以禁止類的拷貝和賦值。

C++中的空類,默認產生哪些類成員函數?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM