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看 剛才我的理解還是有偏差:左右值不是關鍵,減少拷貝次數提高賦值效率是重點)


免責聲明!

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



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