如何在函数中创建局部变量?

时间:2018-02-12 20:36:30

标签: c++ variables constructor scope compilation

假设我有这段代码:

#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;。

这就是为什么当功能结束时,对象“死亡”的原因。它就是目的地。

那么为什么它也不会首先进入构造函数? (假设在那里真正创建了一个本地对象)

幕后是否有任何复制?

提前致谢!

3 个答案:

答案 0 :(得分:4)

以下是发生的事情(您的节目的打印输出和解释):

  • 正常ctor - 这种情况发生在A a1; main
  • 在cpy ctor中 - A a func a1 main a
  • 时会发生这种情况
  • 移动ctor - 当func a1 a2的副本设置为a1时,会发生这种情况(请参阅{{ 3}}作为回报)
  • 在dtor - a2的副本被销毁
  • 在dtor - a1被销毁
  • 在dtor - 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(通过移动)。