我有以下代码。我以为它会失败,即我以为移动构造函数会在输入“发送”功能时执行,并且当再次尝试调用“发送”时,这应该是无效操作(“ a”不再是有效对象,因为它已被移动从)。但是以某种方式执行该代码不会出现任何问题。 输出显示甚至没有执行move构造函数。
#include <iostream>
using namespace std;
struct A {
int *ptr;
A() { cout << "ctor A" << endl; ptr = new int(1); }
A(A&& o) { cout << "move ctor" << endl; ptr = o.ptr; o.ptr = nullptr; }
~A() { cout << "dtor" << endl; delete ptr; }
void send() { cout << *ptr << endl; }
};
bool send(A&& a, int i)
{
if (i == 0) {
cout << "returning" << endl;
return false;
}
cout << "sending" << endl;
a.send();
return true;
}
int main()
{
A a;
if(!send(move(a),0))
send(move(a),1);
}
输出:
ctor A
returning
sending
1
dtor
但是,当我更改“发送”方法以按值接受A对象时,问题恰好出现了我的想象。调用了Move ctor,并且在第二次调用“ send”时,“ a”无效,因此出现了分段错误。
bool send(A a, int i)
{
if (i == 0) {
cout << "returning" << endl;
return false;
}
cout << "sending" << endl;
a.send();
return true;
}
结果:
ctor A
move ctor
returning
dtor
move ctor
sending
Segmentation fault
因此,仅当按值传递移动的对象时,才调用move构造函数。好,知道了。
但是我的问题是:这样声明函数“发送”是否安全,即通过r值引用接受参数,然后多次通过移动对象调用它?我知道std :: move不会真正移动任何东西,只会创建r值引用,但是无论如何:它安全吗?或者换句话说,是否有一条指导方针说“不要这样做”?
答案 0 :(得分:0)
如果实际上在send函数中移动了对象,那么您将看到预期的行为(调用a.send时出现段错误)。例如:
bool send(A &&a, int i)
{
A b = move(a);
if (i == 0) {
cout << "returning" << endl;
return false;
}
cout << "sending" << endl;
a.send();
return true;
}