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看 刚才个人理解仍是有误差:左右值不是关键,减小拷贝次数提升赋值效率是重点)
相关文章
相关标签/搜索