1. 程式人生 > >為什麽復制構造函數的參數需要加const和引用

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

們的 數值 修改 mes cto pre ges 賦值運算符重載 log

為什麽復制構造函數的參數需要加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

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