为什么在此代码代码段中将复制构造函数两次称为两次
Why is the copy constructor called twice in this code snippet?
我正在玩一些事情,以了解复制构造仪的工作方式。但是我无法理解为什么要为x2
创建两次复制构造函数。我会以为当createX()
的返回值复制到x2
中时会被调用一次。
我还查看了一些相关的问题,但是据我所知,我找不到与我在这里问的简单场景。
顺便说一句,我正在使用-fno-elide-constructors
编译,以查看未经优化的情况。
#include <iostream>
struct X {
int i{2};
X() {
std::cout << "default constructor called" << std::endl;
}
X(const X& other) {
std::cout << "copy constructor called" << std::endl;
}
};
X createX() {
X x;
std::cout << "created x on the stack" << std::endl;
return x;
}
int main() {
X x1;
std::cout << "created x1" << std::endl;
std::cout << "x1: " << x1.i << std::endl << std::endl;
X x2 = createX();
std::cout << "created x2" << std::endl;
std::cout << "x2: " << x2.i << std::endl;
return 0;
}
这是输出:
default constructor called
created x1
x1: 2
default constructor called
created x on the stack
copy constructor called
copy constructor called
created x2
x2: 2
有人可以帮助我在这里缺少或忽略什么?
您必须记住的是,函数的返回值是一个独特的对象。当你做
时return x;
用x
复制返回值对象。这是您看到的第一个复制构造函数。然后
X x2 = createX();
使用返回的对象复制初始化x2
,这是您看到的第二份副本。
要注意的一件事是
return x;
如果可以的话,将尝试将x
移至返回对象。如果您制作了一个移动构造函数,您会看到这一点。这样做的原因是,由于本地对象在函数末尾不在范围内,因此编译器将对象视为rvalue,并且只有当找不到有效的过载时,才能将其归还为lvalue。/p>
第一个复制是rextrex
的回报X createX() {
X x;
std::cout << "created x on the stack" << std::endl;
return x; // First copy
}
第二个是从createx的临时返回中创建x2。
X x2 = createX(); // Second copy
请注意,在C 17中,第二份副本被迫被省略。
相关文章:
- g++的分段错误(在NaN上使用to_string两次时)
- 蛇在C++不会连续转两次
- 计算两个代码块的时间复杂度
- 检查一个数组是否包含在另一个数组中,以相反的顺序,至少两次
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 这两个代码片段相似,但显示的结果不同
- 如何使用预处理器指令包含两次具有不同代码的文件?
- 为什么在下面的代码中调用复制构造函数两次
- 相同的代码执行两次:性能差异
- *char数组到字符串(两次运行代码和两个不同的结果)
- 为什么我的代码两次收到此错误"undefined reference to `Pizza::Pizza()' "
- Cmake并需要两次运行才能成功构建代码
- 为什么在此代码代码段中将复制构造函数两次称为两次
- 为什么我的代码两次打印相同的命令行参数
- 在此C 代码示例中发生了两次复制构造函数的调用
- 给定以下代码(在GCC 4.3中),为什么两次转换为引用
- 由于难以理解的原因,我的代码被写了两次
- 为什么代码调用析构函数两次
- 为什么我的代码要求"请输入 2-12 之间的数字:"两次?
- 不知道为什么代码被计算两次