c++ - 为什么在这种情况下不调用 move ctor?
问题描述
#include <iostream>
using namespace std;
class Test {
public:
Test(string value){
cout<<"Ctor "<<value<<endl;
_val=value;
}
Test( Test&& mv): _val(mv._val)
{
mv._val=string();
cout<<"Mv constructor"<<endl;
}
string& get()
{
return this->_val;
}
private:
string _val;
};
void print(Test&& t)
{
cout<<"Stampa val is "<<t.get()<<endl;
}
int main()
{
Test a{"ciao"};
print(move(a));
cout<<"Val of a is "<<a.get()<<endl;
print(Test("test"));
return 0;
}
其输出是(将行号添加到标准输出):
Ctor ciao
Stampa val is ciao
Val of a is ciao
Ctor test
Stampa val is test
为什么在 main 的第 2 行没有调用 mv 语义?我可能会在第四行理解有一个优化,所以只调用了构造函数,但是我无法解释第一步。有任何想法吗?
解决方案
std::move
只是将参数转换为右值(可以稍后移动),它本身不执行移动操作。转换后的右值绑定到引用参数t
,因此在这种情况下不会调用移动构造函数。
std::move 用于指示一个对象 t 可能被“移出”,即允许将资源从 t 有效转移到另一个对象。
特别是,std::move 产生一个 xvalue 表达式来标识它的参数 t。它完全等同于将 static_cast 转换为右值引用类型。
通常调用移动构造函数来初始化对象,它不会在引用绑定中调用(对于左值引用也是如此)。如果您更改要按值传递的参数,则将使用移动构造函数(初始化参数)。例如
void print(Test t)
{
cout<<"Stampa val is "<<t.get()<<endl;
}
顺便说一句:由于复制省略,即使更改为按值传递print(Test("test"));
也不会调用移动构造函数。
BTW2:在移动构造函数中,最好val
根据提供的移动操作移动初始化数据成员std::string
。例如
Test( Test&& mv): _val(std::move(mv._val))
{
cout<<"Mv constructor"<<endl;
}
推荐阅读
- angular - 如何将html2pdf的pdf输出保存到离子文件夹中
- azure-active-directory - 通过 CLI 将成员添加到 Azure Enterprise App
- angular - 从邮件中单击链接时,在默认浏览器 (IE) 以外的浏览器 (Chrome) 上打开 Angular 4 应用程序
- excel - VBA - 删除范围内每个单元格都包含黑色文本的行
- c# - 我需要使用线程来调用一个窗口
- java - Hibernate 查询已获取实体
- android - 如何处理 sqlite 数据库中的“迁移”
- c# - 如何修复“找不到 IdentityModel.dll”?
- node.js - 有没有办法使用 nodejs 在 Godaddy 域中创建/更新“A”类型记录?
- oracle - 由于 org.kitesdk.data.DatasetOperationException,sqoop 增量作业失败