拷贝构造函数调用的时机


拷贝函数何时会被调用呢?最明显的就是用一个类对象初始化另外一个对象的时候
比如X a=X(); 这句语义上就是先创建X()临时对象,再调用X的拷贝构造函数“初始化”a,
这只是语义上的,编译器完全可能优化掉临时对象 。注意区分初始化和赋值(调用assignment operator)

第二种情况是函数按值传参数的时候,包括指针在内都是对原有的值的拷贝 。这种情况容易理解。

第三种情况是一个对象以值传递的方式从函数返回。

为什么要这个时候会调用拷贝构造函数呢?因为在函数内, 所有的变量都是在函数的栈上的,包括那个参数,等函数完了以后都会销毁
所以就必须给它拷贝一份传回。 以下面代码为例,我们看看编译器是如何将对象以值传递方式从函数返回的。

 

 

1.首先声明一个额外的参数,类型上类对象的引用,用来存放返回结果,本例中为&_retvalue。

2.对这个参数利用返回值进行拷贝初始化。过程类似于参数传递,也是要定义一个临时对象sum,用来保存返回值,然后在函数内部调用拷贝构造函数将_retvalue初始化。

 

有时编译器为了减少构造析构的次数,会把事先创建好的对象的引用传进来,然后对其修改,这就是所谓的NRV(Named Return Value (NRV) optimization,具名返回值优化)。仍以上面代码为例,上述代码可能转换为
 

      nrv优化的本质是优化掉拷贝构造函数,去掉它不是生成它。当然了,因为为了优化掉它,前提就是它存在,这个也就是nrv优化需要有拷贝构造函数存在的原因。 nrv优化会带来副作用,不用它的确造成很大的性能损失,知道这个情况就可以了。 

 

第四种情况是非空顺序容器类型的定义,例如vector<string> svec(5);string缺省构造函数创建一个临时对象,然后通过string拷贝构造函数将该临时对象被一次拷贝到vector的五个元素中。

 

第五种情况是将一个类对象插入到容器类型中,例如svec.push_back(string("sfsd"));

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值