gpt4 book ai didi

c++ - 为什么仅当我们返回 *this 时才调用 Copy 构造函数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:02:21 24 4
gpt4 key购买 nike

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)
}

假设我有 Cents object obj 并且正在调用 obj.Add()

现在输出将是

Constructor
Copy constructor

所以我的假设是 Here 通过在 (1) 中返回 *this 我们将 *this 对象值复制到一个新的临时 Cents 对象。这就是复制构造函数被调用的原因。

现在,如果我将第 (1) 行替换为

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

唯一的输出是

Constructor

为什么没有调用复制构造函数?我对第 (1) 行的假设是错误的吗?

最佳答案

这是一种称为复制省略的优化,有时被喜欢缩写词的人称为“(N)RVO”(“(命名)返回值优化”)。

在某些情况下,当一个对象(概念上)在一个地方创建,复制或移动到另一个地方,然后销毁时,程序被允许在它的最终位置创建它。即使省略的构造函数和/或析构函数有副作用,也允许这种优化,就像它们在您的示例中所做的那样。

从函数返回临时变量或局部变量就是其中一种情况。不是在函数的堆栈帧中创建 temp 然后将其复制到调用者的,而是程序可以直接在调用者的帧中创建它。

当您返回*this 时,无法删除拷贝,因为*this 的生命周期超出了函数的范围。从调用者的角度来看,将有两个对象,因此程序必须实际进行复制:

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

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

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

关于c++ - 为什么仅当我们返回 *this 时才调用 Copy 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18252679/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com