【发布时间】:2015-09-06 22:29:34
【问题描述】:
我正在尝试了解 std::move 和 rvalues 在 C++ 11 中的工作原理。我在这样的教程中不断看到类似的示例:
假设我们有这个类:
class Class
{
public:
Class(Class &&b)
{
a = b.a;
}
int *a;
}
int main()
{
Class object1(5);
Class object2(std::move(object1));
}
main 函数的第二行运行后,object1 会发生什么?
如果 object1 的内存被“移动”到 object2,那么这个复制构造函数的意义何在?因为我们正在丢失 object1 的内存只是为了在内存的不同位置获得完全相同的值?这个有什么用处?
编辑:问题不是重复的。重复的候选者更广泛,因为它甚至没有代码 sn-p。
Edit2:我刚刚尝试了这段代码:
class trial
{
public:
trial()
{
a = (int*)malloc(4);
}
trial(trial& rv)
{
this->a = rv.a;
rv.a = NULL;
}
int *a;
};
int main() {
cout << "Program Started" << endl;
trial a1;
trial a2(a1);
return 0;
}
我已经检查了 a1 和 a2 的内部结构。它给出了与此代码完全相同的结果:
class trial
{
public:
trial()
{
a = (int*)malloc(4);
}
trial(trial&& rv)
{
this->a = rv.a;
rv.a = NULL;
}
int *a;
};
int main() {
cout << "Program Started" << endl;
trial a1;
trial a2(std::move(a1));
return 0;
}
不同之处在于复制构造函数,其中之一不使用移动语义。只是对象的简单引用。如果我们也通过引用传递,则不会发生复制,但我们将不得不通过执行rv.a = NULL 来稍微丢失第一个对象,以避免通过释放a1 意外释放a2 的内存。所以我设置了rv.a = NULL。
当我使用类试验的右值复制构造函数,但不使用右值构造函数中的行rv.a = NULL 时,整数指针a 在a1 和a2 中显示相同的地址,当我放一个return 0 行的断点。那么这与仅通过引用传递有什么不同呢?看起来我们可以通过引用传递来做同样的事情。
【问题讨论】:
-
为了真正使这种构造成为“移动”,您需要将
b.a设为空,否则您只需执行浅层复制。
标签: c++ std move-semantics