程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 拷貝構造函數和賦值操作符的一些細節

拷貝構造函數和賦值操作符的一些細節

編輯:關於C語言

從開始學C++就一直記得“如果一個類沒有定義拷貝構造函數或者賦值操作符,編譯器會為它生成一個拷貝構造函數和一個賦值操作符。”
  這個說法其實挺含糊的。今天看書的時候看到的一個例子,就讓我感到十分“出乎意料”。
  #include <stdio.h>
  struct X { X() { };
  template<typename T> X( const T& ) { printf("templated X copy constructor.");}
  template<typename T> X& operator=( const T& ) { printf("templated X assignment operator.");} };
  int main(int argc, char** argv) { X x1;X x2(x1);X x3;x3 = x1;}
  這個程序編譯後,執行結果是啥?答案:啥也沒有!兩個函數模板都沒有被調用到。
  原因說起來並不十分復雜,但能看出,我對C++的細節還是不夠清楚。好,現在細節來了:
  C++標准(ISO/IEC 14882:2003(E))12.8.2寫的清楚:A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments (8.3.6)。
  要點:帶有模板參數的函數模板,不算是構造函數。
  所以上面例子中聲明的template<typename T> X(const T&)這個函數不是拷貝構造函數。
  並且按照這段話對拷貝構造函數的定義,上面的類定義裡沒有顯式地定義任何拷貝構造函數。
  C++標准接著說:If the class definition does not explicitly declare a copy constructor, one is declared implicitly.這個是學過C++的人基本都知道的事情。所以編譯器要為上面的類生成一個隱式的拷貝構造函數。
  編譯器生成的隱式拷貝構造函數,所做的事情就是對類的所有成員一一做淺拷貝,自然沒有任何輸出。
  賦值操作符的情形類似。標准定義為:A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const  X&, volatile  X& or const  volatile X&.即:賦值操作符必須是一個非模板的、非靜態的成員函數,而且只能有一個參數。這一點和拷貝構造函數還不同。拷貝構造函數可以有多個參數,只要第一個是X&或者cv-qualified X&類型,而其後的所有參數都有缺省值即可。
  程序真正執行的時候,兩個函數模板均未被調用到,所以什麼輸出也沒有。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved