我正在玩一些东西来了解复制构造函数的工作原理。但我无法理解为什么复制构造函数被调用两次以创建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
如果可以,将尝试移入返回对象。如果您创建了一个移动构造函数,您就会看到它被调用。这样做的原因是,由于局部对象在函数结束时超出范围,编译器将该对象视为右值,并且只有在未找到有效重载时才会回退到将其作为左值返回。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句