我正在玩一些东西来了解复制构造函数的工作原理。但是我不明白为什么复制构造函数被调用两次来创建x2
。我会假设它会在 createX()
的返回值被复制到 x2
时被调用一次。
我还查看了一些关于 SO 的相关问题,但据我所知,我找不到与我在这里问的相同的简单场景。
顺便说一句,我正在使用 -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
移动到返回对象中。如果你做了一个移动构造函数,你会看到这个被调用。这样做的原因是,由于局部对象在函数末尾超出范围,编译器将对象视为右值,只有当它没有找到有效的重载时,它才会回退到将其作为左值返回。
关于c++ - 为什么在这段代码片段中复制构造函数被调用了两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54929274/