c_s*_*ent 14 c++ copy-constructor c++14
我正在玩一些东西来理解复制构造函数的工作原理.但我无法理解为什么复制构造函数被调用两次才能创建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;
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
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
Run Code Online (Sandbox Code Playgroud)
有人可以帮助我,我想要或忽略这里?
Nat*_*ica 19
你必须记住的是函数的返回值是一个独特的对象.当你这样做
return x;
Run Code Online (Sandbox Code Playgroud)
复制初始化返回值对象x.这是您看到的第一个复制构造函数调用.然后
X x2 = createX();
Run Code Online (Sandbox Code Playgroud)
使用返回的对象复制initialize x2,这是您看到的第二个副本.
有一点需要注意的是
return x;
Run Code Online (Sandbox Code Playgroud)
x如果可以,将尝试进入返回对象.如果你做了一个移动构造函数,你会看到这个叫做.这样做的原因是,由于本地对象在函数末尾超出范围,编译器会将对象视为右值,并且只有在找不到有效的重载时才会将其作为左值返回.
Jar*_*d42 12
第一个副本是createX的回报
X createX() {
X x;
std::cout << "created x on the stack" << std::endl;
return x; // First copy
}
Run Code Online (Sandbox Code Playgroud)
第二个是通过createX从临时返回创建x2.
X x2 = createX(); // Second copy
Run Code Online (Sandbox Code Playgroud)
请注意,在C++ 17中,强制要求省略第二个副本.
| 归档时间: |
|
| 查看次数: |
1219 次 |
| 最近记录: |