为什么只有当我们返回* this时才调用Copy构造函数? [英] Why is Copy constructor being called only when we return *this?

查看:185
本文介绍了为什么只有当我们返回* this时才调用Copy构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  Class Cents(){
int m_val;
public:
Cents(int x = 0){cout<<Constructor;}
Cents(const Cents& src){cout< $ c Cents Add(int val){m_val = val; return * this} // --->(1)
}

Cents对象obj 并且正在调用 obj.Add()



现在输出为


构造函数

复制构造函数


<因此我的假设是通过返回 * this 在(1)中复制 *这个对象值到一个新的临时Cents对象。这就是为什么复制构造函数被调用。



现在,如果我用

   

唯一的输出是


构造函数


为什么不调用复制构造函数?我的假设关于行(1)错了吗?

解决方案

这是称为 copy elision 的优化,有时称为



在某些情况下,当一个对象(概念上)在一个地方创建,复制或移动到另一个,然后销毁,程序被允许在它的最终位置创建它。



返回一个临时变量或一个局部变量,从一个函数是这些情况之一。代替在函数的栈框架中创建 temp ,然后将其复制到调用者的框架,程序可以直接在调用者的框架中创建它。



当您返回 * this 时,该副本不能被省略,因为 * this 一生超越功能。从调用者的角度来看,将有两个对象,因此程序必须实际创建一个副本:

  
Cents copy = original.Add(42);

//copy和original都存在:对象必须已被复制。

有关通过此优化可以省略哪些操作的详细信息,请参阅C ++ 11标准, 12.8 / 31。


Class Cents(){  
 int m_val;  
 public:  
  Cents(int x=0){ cout<<"Constructor";}
  Cents(const Cents& src){ cout<<"Copy constructor"}
  Cents Add(int val){m_val=val; return *this}  // --->(1)
 }  

Assume I have Cents object obj and am calling obj.Add()

Now the output will be

Constructor
Copy constructor

So my assumption was Here by returning *this in (1) we are copying the *this object value to a new temporary Cents object. That's why copy constructor is called.

Now if I replace line (1) with

Cents Add(int val){ Cents temp;return temp;}  // --->(2)

the only output is

Constructor

Why is the copy constructor not being called? Is my assumption about line (1) wrong?

解决方案

This is an optimisation known as copy elision, sometimes called "(N)RVO" (for "(named) return value optimisation") by those who like acronyms.

In certain circumstances, when an object is (conceptually) created in one place, copied or moved to another, and then destroyed, the program is allowed to create it in its final place instead. This optimisation is allowed even if the elided constructor and/or destructor have side effects, as they do in your example.

Returning a temporary, or a local variable, from a function is one of these situations. Instead of creating temp in the function's stack frame then copying it to the caller's, the program may instead create it directly in the caller's frame.

When you return *this, the copy can't be elided, since *this has a lifetime beyond the function. From the caller's point of view, there will be two objects, so the program must actually make a copy:

Cents original;
Cents copy = original.Add(42);

// "copy" and "original" both exist: the object must have been copied.

For full details of which operations can be elided by this optimisation, see the C++11 Standard, 12.8/31.

这篇关于为什么只有当我们返回* this时才调用Copy构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆