关于拷贝构造函数

O湛狼O 2010-05-25 01:38:48
请问各位,下面这篇文章有那里是错的吗?麻烦指正一下。


相信许多人对拷贝构造函数都有两个疑问:
1、为什么拷贝构造函数(或者系统默认的拷贝构造函数)必须用引用来进行参数传递?
2、可不可以用指针来代替拷贝构造函数?

实际上拷贝构造函数也是构造函数的一个重载,所以自己定义了拷贝构造之后,默认的构造函数就没有了,因为其实已经重定义了构造函数,而形参设置为类的引用,这是拷贝构造的特点,如果不这样设置形参,那么这个就不能叫拷贝构造函数了,那为什么要用引用来进行按地址传递参数呢?我们先假设不用按地址的情况,即假设test(test x);这个是拷贝构造函数,然后,我们生成test 类的对象b和a,用a来初始化b,这时候,编译器就会去寻找有没有以test类对象为形参的函数,然后调用这个函数来进行初始化,幸运的是,它找到了,这个函数就是前面我们假设的test(test x),因为这时候是按值传递,那么这时候这个拷贝构造函数就会生成一个临时的test类对象来接受实参的值,那么这种情况就是用实参去初始化构造函数生成的临时对象,这时候怎么初始化呢?当然又要调用这个拷贝构造函数去初始化形参啦,然后再用实参去初始化拷贝构造函数生成的临时对象,然后怎么初始化呢?当然又得调用拷贝构造函数啦。。。。。这样就会无穷无尽的嵌套调用下去,直到堆栈空间耗尽,所以编译器会禁止这种情况。
那么怎么解决这个问题呢?就是把拷贝构造函数的形参设置为类的引用啦。。。这样就是地址传递,那么久不会出现上面的重复调用拷贝构造函数的情况啦。。。
拷贝构造函数的形参问题,上面已经说过,按值传递是不行的,需要按地址传递,那么引用和指针都是按地址传递,他们的效果是一样的,即是说用指针同样是可以完成功能的,那为什么不用指针呢?同样用上面那个例子来说明吧,我们假设一个以指针作为形参的拷贝构造函数test(test * x);然后生成test类的对象 a,现在我们再生成一个对象b,同时用a给b初始化,那么这时候就会调用拷贝构造函数,即test(test * x),但是拷贝构造函数的形参不能接受一个非地址值,那么我们要怎么给b初始化呢?那就要取地址啦,所以初始化方式是这样的test b(&a);这样虽然效果是一样的,但是使用起来就不如引用方便,引用可以直接用test b(a),这种方式,使得代码更加直观和方便,只是个人意见。如有错误,请指出。
...全文
138 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
mskmc_mc 2010-05-25
  • 打赏
  • 举报
回复
1、为什么拷贝构造函数(或者系统默认的拷贝构造函数)必须用引用来进行参数传递?
答:之所以使用引用,是因为效率问题,如果参数是一个类对象,会引起建立临时对象,如果是很大的类,对性能会很影响。
2、可不可以用指针来代替拷贝构造函数?
答:可以,只不过,指针的操作方式很特别,虽然解决了效率问题,但总是要用*号解引用,这样会对程序的后期维护增加难度。
liutengfeigo 2010-05-25
  • 打赏
  • 举报
回复
复制构造函数 是会在这样的列子中出问题。
class1 b(初始化);
//假如没有自己搞着函数。
class1 c(a);
class1 d = clsaa(a);
class1 *e = new class1(a);
class1 a = b;(这些都会调用系统默认的复制构造函数)

还有假如自己的类被按值传递和返回对象市都会调用这函数。

C++ PRIMER PLUS 385面这样解释的。
由于按值传递对象将调用复制构造函数,所以因该按引用传递对象。这样既可以节省调用构造函数的时间以及储存新的空间。

主要还是防止其按值传递。。。。怕出现2个指向同一对象的指针。。。。。。必须定义深度复制构造函数的原因在于,一些类成员是使用new初始化的,指向数据的指针。而不是数据本身。
还有一些我就不看了,我是昨天刚好看到这里,今天早上写了一个这样的代码。
错了别怪我。。。。。
liutengfeigo 2010-05-25
  • 打赏
  • 举报
回复
这。。。。学习了~~
shnxin 2010-05-25
  • 打赏
  • 举报
回复
使用指针完全可以实现这种行为,但如你所述,使用引用更加直观和方便。但在代码中完全可以定义一个自己的传指针的拷贝构造函数,直接传值时调用引用的版本,而传指针时则调用指针的版本。
taodm 2010-05-25
  • 打赏
  • 举报
回复
楼主就别乱看网文了吧,去看C++之父亲自写的《C++语言设计与演化》吧
elegant87 2010-05-25
  • 打赏
  • 举报
回复
这个问题没有研究过。只知道引用就是一个别名。
pengzhixi 2010-05-25
  • 打赏
  • 举报
回复
这个问C++之父吧。
selooloo 2010-05-25
  • 打赏
  • 举报
回复
拷贝构造函数 要带const test(const test& x);
test(test * x);只被当作构造函数,不会当作拷贝构造函数
healer_kx 2010-05-25
  • 打赏
  • 举报
回复
........穷无尽的嵌套调用下去,直到堆栈空间耗尽,所以编译器会禁止这种情况。

结论用“所以”行文,给人一种这个是缘由的感觉,而实际上,这个不是因果关系。
只是反证其行不通,构造函数当然是传递引用来办事了,Java。,C#也是如此啊,我们要用某个对象实例当原型,为什么不是穿它的指针或者引用呢?这是天经地义的事情。

至于为什么是饮用,不是指针,我觉得那个是无所谓的事情。用一个对象的指针来构造是可能的,可是以copy ctor的形式出现,让人不爽而已。

64,691

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧