之前写拷贝构造函数的时候,以为参数为引用,不为值传递,仅仅是为了减少一次内存拷贝。然而今天看到一篇文章发现自己对拷贝构造的参数理解有误。 参数为引用,不为值传递是为了防止拷贝构造函数的无限递归,最终导致栈溢出。

    下面来看一个例子:
  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看 刚才我的理解还是有偏差:左右值不是关键,减少拷贝次数提高赋值效率是重点)

C++ 为什么拷贝构造函数参数必须为引用?赋值构造函数参数也必须为引用吗?的更多相关文章

  1. 细说PHP-5.3.4变量的引用赋值

    变量总是传值赋值.也就是说,当讲一个表达式的值赋予一个变量时,整个原始表达式的值被赋值到目标变量.这意味着,当一个变量的值赋予另个一变量时,改变其中一个变量的值,将不会影响到另一个变量.PHP中提供了 ...

  2. C++引用指针 & 构造函数

    近来回转 C++的学习,脑子又被搞得了一团迷(简直不要忘得太快.....    ) 过后静下来想一想,还是因为有些东西没搞清楚导致,所以理了理两个容易搞迷糊的地方. 1. 引用与指针 C++进行传值更 ...

  3. C++中使用引用作为函数参数的优点

    1.传递引用给函数与传递指针的效果是一样的.这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标 对象(在主调函数中)的操作. ...

  4. C++ 引用、构造函数、移动语义

    1.引用 C++中的引用主要用作函数的形参,接近于const指针,必须在创建时初始化. 以Person类为例,如下: Person p;                          //调用P的 ...

  5. c++类大四个默认函数-构造函数 析构函数 拷贝构造函数 赋值构造函数

    每个类只有一个析构函数和一个赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其它的称为普通构造函数).对于任意一个类A,如果不编写上述函数,C++编译器将自动为A 产生四个缺省的函数,例如: A ...

  6. C++ 拷贝构造函数和赋值构造函数

    转自:http://blog.chinaunix.net/uid-28662931-id-3496326.html 一.拷贝构造函数 int main(int argc, char * argv[]) ...

  7. C++类中函数(构造函数、析构函数、拷贝构造函数、赋值构造函数)

    [1]为什么空类可以创建对象呢? 示例代码如下: #include <iostream> using namespace std; class Empty { }; void main() ...

  8. C++中,引用作为函数参数

    引用作为函数参数 C++之所以增加引用类型, 主要是把它作为函数参数,以扩充函数传递数据的功能. ———————————————————— c++,函数传参:(1)将变量名作为实参和形参.这时传给形参 ...

  9. delphi的一些语法知识 以及参数传递问题,按引用方式传递参数,按值方式传递参数

    //delphi中exit,abort,break,continue 的区别 exit: 退出函数体abort: 遇到异常,安静处理,就是不显示不提示break: 退出当前循环体,包括for ,whi ...

随机推荐

  1. 【所见即所得】textarea 精确限制字数、行数,中、英、全半角混检 。源码带注释

    主要解决难点: 1 中文 全角2字符深深的恶意 2 多行输入textarea 手动,自动换行问题 3 获得每行内容 原创,转载请注明出处! <!DOCTYPE html PUBLIC " ...

  2. 退役&&搬家

    牡丹江与鞍山两站作为最后的结束站.一银一铜就此结束了~ 此博客用来怀念ACM就此保留并不添加任何其它与其无关内容. ------------------------------------------ ...

  3. Jenkins的安装与配置

    资源下载: --jenkins的war包 首先从http://jenkins-ci.org/下载最新的jenkins版本,最新版本为1.594,下载的文件载体为jenkins.war: Jenkins ...

  4. 转!!java事务的处理

    java的事务处理,如果对数据库进行多次操作,每一次的执行或步骤都是一个事务.如果数据库操作在某一步没有执行或出现异常而导致事务失败,这样有的事务被执行有的就没有被执行,从而就有了事务的回滚,取消先前 ...

  5. ToolBar 修改边距

    <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android ...

  6. JS学习之事件流

    本文是原创文章,如需转载,请注明文章出处 JS和AS师出同源,所以事件流的3个阶段也跟AS一样,分别是捕获阶段,目标阶段,冒泡阶段. 下面写了个例子可以清晰的看出事件流的顺序: eventTest.h ...

  7. 不在折腾---hbase-0.96.2-hadoop2

    首先安装好zookeeper集群 上传hbase安装包 解压 配置hbase集群,要修改3个文件 * 修改hbase-env.sh 设置JAVA_HOME: export JAVA_HOME=... ...

  8. Web之路笔记之二 - CSS Positioning

    CSS中控制各个Block element的位置方式之一,tag为position,有4种属性. 1. static 一般网页默认的属性,表示element根据页面正常流(normal flow)进行 ...

  9. iPhone5停留在语音的界面,提示按三次home键,无法继续下去

    不知道之前用户是怎么操作的,可能是刷机或恢复出厂设置.穷人,没用玩过iPhone. 根据提示关键词,网上搜索,发现只需要按三次home,三次锁屏,三次锁屏,最后再三次home就可以了. 试了两次,还真 ...

  10. (转载)数据库出现ORA-00283/ORA-01610的问题

    在这里需要感谢棉花糖给予无私帮助,真的谢谢他!http://blog.itpub.net/67668/viewspace-353270/处理过程可以参照http://www.itpub.net/vie ...