【整理】為什么復制構造函數的參數需要加const和引用


為什么復制構造函數的參數需要加const和引用

一.引言

1.0在解答這個問題之前,我們先跑個小程序,看下調用關系。

 1 #include <iostream>
 2 using namespace std;  3 class CExample  4 {  5 public:  6     CExample(int x) :m_nTest(x) //帶參數構造函數
 7  {  8         cout<< "constructor with argument."<<endl;  9  } 10     CExample(const CExample & ex) //拷貝構造函數
11  { 12         m_nTest = ex.m_nTest; 13         cout << "copy constructor."<<endl; 14  } 15     CExample& operator = (const CExample &ex)//賦值函數(賦值運算符重載)
16  { 17         cout << "assignment operator." << endl; 18         m_nTest = ex.m_nTest; 19         return *this; 20  } 21     void myTestFunc(CExample ex) 22  { 23  } 24 private: 25     int m_nTest; 26 }; 27 
28 int main() 29 { 30     CExample aaa(2); 31     CExample bbb(3); 32     bbb = aaa; 33     CExample ccc = aaa; 34  bbb.myTestFunc(aaa); 35     system("pause"); 36     return 0; 37 }

1.1【輸出結果】

1.2【分析結果】

第一個輸出: constructor with argument.     //CExample aaa(2);

這里創建了變量aaa,在創建的同時還帶有參數2,那就調用帶參數的構造函數

第二個輸出:constructor with argument.     //CExample bbb(3);

分析同第一個

第三個輸出:assignment operator.                //bbb = aaa;

bbb之前已經創建了,所以這個不會調用構造函數,而只是將aaa賦值給bbb,所以調用賦值函數
第四個輸出:copy constructor.                      //CExample ccc = aaa;

這個和上一個的區別就在於:bbb之前已經創建過了,而這里的ccc是在這條語句才創建的,所以這里是在創建ccc的同時將aaa賦值給ccc,所以這句調用的肯定是構造函數,又因為需要將aaa賦值給ccc,所以調用的是拷貝構造函數。

第五個輸出:copy constructor.                     //  bbb.myTestFunc(aaa);
這里是調用了一個自己寫的myTestFunc函數,其中這個函數中的參數沒有采用引用,那就是值傳遞的方式。就是編譯器先創建一個類型為CExample名稱為ex的對象,然后將aaa的值傳遞給ex(值傳遞方式的特性),將相當於要執行一條CExample ex = aaa的語句。經第四個輸出的分析可知,這需要調用拷貝構造函數。所以輸出copy constrctor。

 

二.解答問題

2.1為什么要用引用?

  【錯誤答案】個人第一反應:為了減少一次內存拷貝。

  【正確答案】由上節的第五個輸出分析可知,在執行bbb.myTestFunc(aaa);時,其實會調用拷貝構造函數。如果我們的拷貝構造函數的參數不是引用,那么在bbb.myTestFunc(aaa);時,調用CExample ex = aaa;,又因為ex之前沒有被創建,所以又需要調用拷貝構造函數,故而又執行CExample ex = aaa;,就這樣永遠的遞歸調用下去了。

  所以, 拷貝構造函數是必須要帶引用類型的參數的, 而且這也是編譯器強制性要求的。

 

2.2為什么要用const?

  【正確答案】如果在函數中不會改變引用類型參數的值,加不加const的效果是一樣的。而且不加const,編譯器也不會報錯。但是為了整個程序的安全,還是加上const,防止對引用類型參數值的意外修改。

 

——如有不對的地方,非常歡迎給予指導!

——【感謝】資料來源於http://blog.csdn.net/tunsanty/article/details/4264738

——【感謝】資料來源於http://blog.csdn.net/sinat_36053757/article/details/70597567


免責聲明!

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



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