如何调用移动构造函数?

时间:2018-07-14 11:12:13

标签: c++ c++11

我有以下代码:

#include<iostream>
using namespace std;
class A{
    int size;
    double *arr;

public:
    A(int len):size(len)
    {
        cout<<"ctor called"<<endl;
        arr=new double[size];
    }
    A(const A &rhs)
    {
        cout<<"calling copy ctor"<<endl;
        size=rhs.size;
        arr=new double[size];
    }
    A(A&& rhs)
    {
      cout<<"caling move constructor"<<endl;
      size=rhs.size;
      arr=rhs.arr;
      rhs.arr=nullptr;
    }
    ~A()
    {
        cout<<"Calling Dtor"<<endl;
        delete[] arr;
        size=0;
        arr=NULL;
    }
};
A createVector()
{
    cout<<"Creating object"<<endl;
    A a(20);
    cout<<"returning after creating object a"<<endl;
    return (a);
}
void foo(A v)
{
    cout<<"Class A object rcvd"<<endl;
    return;
}
int main()
{
    //cout<<"a has been rcvd"<<endl;
    foo(createVector());
    return 0;
}

我已经传递了一个'A'类型的临时对象(已由另一个函数返回)。我期望调用Move构造函数,但是我得到以下输出:

Creating object
ctor called
returning after creating object a
Class A object rcvd
Calling Dtor

为什么不调用Move Constructor? 同样,如果更改代码如下:

foo(createVector())----->foo(move(createVector()));

我得到以下输出:

Creating object
ctor called
returning after creating object a
caling move constructor
Class A object rcvd
Calling Dtor
Calling Dtor

为什么两次调用Destructor?

1 个答案:

答案 0 :(得分:2)

  

为什么不调用Move构造函数?

由于对移动进行了优化,因此无需调用move构造函数。 createVector创建其A对象时,通常不会在本地变量中创建对象。而是在通常的位置为返回值创建对象。此返回值到达main为其指定的位置,即其“类型'A'的临时对象”。由于此临时变量是通过值传递给另一个函数的,因此通常在此类参数处构造它。

因此,当createVector创建其名为A的{​​{1}}对象时,a的位置已经是a传递给{ {1}},不需要移动(直到您明确请求移动)。麾!您的编译器效率很高!忽略它,继续关注更重要的问题。 (如果这不仅仅是尝试理解移动语义,那么您可能正在编写错误的代码。)

  

为什么两次调用Destructor?

因为您强迫两个对象存在。在这种情况下,由main返回的临时对象被强制放置在与用作foo参数的对象不同的位置。两者都需要销毁。 (从对象移开可能会使该对象处于无法使用的状态,但仍然是一个需要销毁的对象。无法使用的状态的确必须具有足够的一致性以使析构函数能够处理。)