假设我有这段代码:
#include <iostream>
using namespace std;
class A{
public:
A() { cout << "In normal ctor\n"; }
A(const A& a) { cout << "In cpy ctor\n"; }
A(A&& a) { cout << "In move ctor\n"; }
~A() { cout << "In dtor\n"; }
};
A func(A a) {
return a;
}
void main(){
A a1;
A a2 = func(a1);
}
输出如下:
In normal ctor
In cpy ctor
In move ctor
In dtor
In dtor
In dtor
现在我无法理解功能内部发生的事情&#39; func&#39;&#39;。
当a1被发送到该功能时,该功能不会通过参考来接收它,而是它会创建&#39;&#39;&#39;它自己的a1版本是&#39; a&#39;。
这就是为什么当功能结束时,对象“死亡”的原因。它就是目的地。
那么为什么它也不会首先进入构造函数? (假设在那里真正创建了一个本地对象)
幕后是否有任何复制?
提前致谢!
答案 0 :(得分:4)
以下是发生的事情(您的节目的打印输出和解释):
A a1;
main
A a
func
a1
main
a
func
a1
a2
的副本设置为a1
时,会发生这种情况(请参阅{{ 3}}作为回报)a2
的副本被销毁a1
被销毁a2
被销毁我认为关键是要了解移动构造函数在创建func
中的作用。您的A
按值返回a2
,应将其复制到{{1}}。但是,C ++编译器意识到您的程序在赋值后无法使用原始值,因此它通过调用移动构造函数来优化调用。
答案 1 :(得分:3)
void main(){
A a1; -- > Normal constructor
A a2 = func(a1); --> Copy(a1 to a), Move(a to a2), destructor(a)
} --> destructor a1, a2
这就是您按顺序查看输出的原因。
答案 2 :(得分:3)
func通过副本传递A(I.E.没有引用,它不是指针等)。这就是调用复制构造函数的原因。创建它之后,它将移动到a2的位置,从而移动构造函数。移动后,a被销毁(因为func返回并且超出范围),然后是a1和a2(因为main返回)。
你问为什么它不会进入构造函数,但确实如此。对于每个A你创建一个不同的构造函数被调用,首先是a1(通常)然后是func(通过副本),然后是a2(通过移动)。