C++ 爲何拷貝構造函數參數必須爲引用?賦值構造函數參數也必須爲引用嗎?

以前寫拷貝構造函數的時候,覺得參數爲引用,不爲值傳遞,僅僅是爲了減小一次內存拷貝。然而今天看到一篇文章發現本身對拷貝構造的參數理解有誤。 參數爲引用,不爲值傳遞是爲了防止拷貝構造函數的無限遞歸,最終致使棧溢出。函數

    下面來看一個例子:
  1. class test
  2. {
  3. public:
  4. test()
  5. {
  6. cout << "constructor with argument\n";
  7. }
  8. ~test()
  9. {
  10. }
  11. test(test& t)
  12. {
  13. cout << "copy constructor\n";
  14. }
  15. test&operator=(const test&e)
  16. {
  17. cout << "assignment operator\n";
  18. return *this;
  19. }
  20. };
  21. int _tmain(int argc, _TCHAR* argv[])
  22. {
  23. test ort;
  24. test a(ort);
  25. test b = ort ;
  26. a = b;
  27. return 0;
  28. }
輸出:
若是這些知識你都能理解。下面就來解釋一下爲何值傳遞會無限遞歸!
若是複製構造函數是這樣的 : 
  1. test(test t);
咱們調用
  1. test ort;
  2. test a(ort); --> test.a(test t=ort)==test.a(test t(ort))
  3. -->test.a(test t(test t = ort))
  4. ==test.a(test t(test t(ort)))
  5. -->test.a(test t(test t(test t=ort)))
  6. ...
  7.     就這樣會一直無限遞歸下去。
到這裏,咱們也就明白了,爲何拷貝構造函數的參數必定要爲引用,不能爲值傳遞的緣由了。
 
接下來,咱們再測試一下賦值構造函數的參數,若是咱們把它的參數也改成值傳遞,作一個測試。
  1. class test
  2. {
  3. public:
  4. test()
  5. {
  6. cout << "constructor with argument\n";
  7. }
  8. ~test()
  9. {
  10. }
  11. test(test& t)
  12. {
  13. cout << "copy constructor\n";
  14. }
  15. test&operator=(test e)
  16. {
  17. cout << "assignment operator\n";
  18. return *this;
  19. }
  20. };
  21. int _tmain(int argc, _TCHAR* argv[])
  22. {
  23. test ort;
  24. test a(ort);
  25. test b = ort ;
  26. a = b;
  27. return 0;
  28. }
輸出:
賦值構造函數若是爲值傳遞,僅僅是多了一次拷貝,並不會無限遞歸。
 
總結:拷貝構造函數的參數必須爲引用。賦值構造函數參數既能夠爲引用,也能夠爲值傳遞,值傳遞會多一次拷貝。所以建議賦值構造函數建議也寫爲引用類型。(CKK看 剛纔個人理解仍是有誤差:左右值不是關鍵,減小拷貝次數提升賦值效率是重點)
相關文章
相關標籤/搜索