c++ - 如何调用移动构造函数?
问题描述
我有以下代码:
#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
为什么没有调用移动构造函数?此外,如果更改代码如下:
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 两次?
解决方案
为什么没有调用移动构造函数?
没有调用移动构造函数,因为移动已经被优化掉了。创建对象时,createVector
它A
不会在通常用于局部变量的位置创建对象。相反,该对象是在返回值的通常位置创建的。这个返回值被送到main
为它指定的地方,即它的“'A'类型的临时对象”。由于这个临时值是按值传递给另一个函数的,所以它是在这些参数的通常位置构造的。
因此,当createVector
创建其A
名为 的对象时a
, 的位置a
已经是传递main
给的正确位置foo
,不需要移动(除非您明确请求移动)。麾!你的编译器效率很高!忽略它并继续关注更重要的问题。(如果这不仅仅是试图理解移动语义,那么您可能正在编写糟糕的代码。)
为什么要调用 Destructor 两次?
因为你强迫两个物体存在。在这种情况下,由返回的临时对象createVector
被强制到与用作参数的对象不同的位置foo
。两者都需要销毁。(从一个对象移动可能会使该对象处于不可用状态,但它仍然是一个需要销毁的对象。不可用状态确实需要足够连贯,以便析构函数处理。)
推荐阅读
- java - 使用 Servlet 自动登录和注销
- python - 对于python中的列表,如何实现以下功能?
- javascript - 在元素上使用 querySelector 时未定义或为 null
- r - R ggscatter p值四舍五入?
- c# - How is it possible that a variable gets overwritten afterwards?
- ftp - 通过 filezilla 或 winScp 提交 JCL
- spring-boot - 工厂已定义导致组件初始化失败
- ruby - What is the best Ruby algorithm to divide an array into groups with a minimum and maximum length?
- laravel - 如何在 laravel 5.7 中使用 muiti 中间件进行路由
- java - Springboot:org.springframework.beans.factory.BeanCreationException:创建类路径资源中定义的名称为“showAuthorsView”的bean时出错