为什么在移动构造函数的末尾将基本类型值设置为零

时间:2015-11-02 03:11:16

标签: c++

MemoryBlock(MemoryBlock&& other)

   : _data(nullptr)

   , _length(0)
{
   std::cout << "In MemoryBlock(MemoryBlock&&). length = " 
             << other._length << ". Moving resource." << std::endl;

   _data = other._data;
   _length = other._length;

   // Release the data pointer from the source object so that
   // the destructor does not free the memory multiple times.
   other._data = nullptr;
   other._length = 0;
}

以下是Microsoft msdn的示例。 它的size_t并不是免费的。所以你不必将它分配给0。 为什么将other._length设置为0? THX

3 个答案:

答案 0 :(得分:1)

为了完整起见,据我所知,没有具体的技术原因。退出其范围时,other将被销毁,因为您在移动构造函数中将其定义为右值引用。

您必须确保将移动构造函数/赋值中的右值引用保留在 destructable 状态,通过将nullptr分配给_data(通常是您)必须确保指针指向null)。 _length = 0只是为了完整性(或习惯):移动数据,数据指针为空,长度必须为零。

答案 1 :(得分:0)

这样做通常是一个好主意,因此您可以保持更严格的不变性,使类的其他部分更容易推理,并且如果检查需要更少。举一个具体的例子,假设MemoryBlock有一个返回长度的length()方法。如果你没有在移动时设置_length,那么这个length()方法将需要对_data的if检查不为null。通过在移动后将其设置为零,此方法可以简单地返回_length。

答案 2 :(得分:0)

将对象A的内容移动到另一个对象B后,A仍然存在。它会在示波器的末尾销毁,同时可以再次使用。您实际上无法指望A的内容在移动之后是什么,但是您可以为其分配新的值。例如,这是合法的代码:

std::string a = "Some string";
std::cout << "a before move: " << a << endl;
std::string b = std::move(a);
std::cout << "a after move: " << a << endl;
std::cout << "b after move: " << b << endl;
a = "Some other string";
std::cout << "a after reassignment: " << a << endl;

它在Visual Studio下生成:

a before move: Some string
a after move:
b after move: Some string
a after reassignment: Some other string