-1

我正在尝试了解 C++ 的新功能,即移动构造函数和赋值X::operator=(X&&),我发现了有趣的示例 ,但唯一我什至不理解但更不同意的是移动 ctor 和赋值运算符中的一行(在下面的代码中标记):

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

   // Copy the data pointer and its length from the 
   // source object.
   _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 = NULL;
   other._length = 0;//WHY WOULD I EVEN BOTHER TO SET IT TO ZERO? IT DOESN'T MATTER IF IT'S ZERO OR ANYTHING ELSE IT IS JUST A VALUE.
}

所以我的问题是:我必须将 lenght_ 的值设置为零还是可以保持不变?不会有任何内存泄漏,也不会少一个表情。

4

6 回答 6

6

因为“移出”的对象最终还是会被破坏,所以你必须让它保持一致的状态。当然,具体如何执行此操作取决于您的对象,在这种情况下,这显然意味着清空数据指针并将长度设置为零。

于 2010-06-27T17:02:22.640 回答
0

将值设置为零只会暴露一致性。但是,答案实际上取决于打算如何使用 _length 来销毁对象。如果没有使用长度来确定是否应该删除 _data(当移动的对象超出范围时),那么我们可以说在移动对象时忽略 _length 是安全的。只需确保在任何派生类型中保持这种一致性,并确保记录您忽略 _length 的决定。

于 2012-10-07T12:43:21.117 回答
0

这个问题很难得到明确的答案。移动语义是新的,C++ 社区仍在学习如何正确使用它。

我看到的一个合理规则是“移离”对象必须安全地销毁并且能够被分配一个新值。不必设置_length为零来满足该规则,坦率地说,我不确定用 int 表示无效状态的好值是多少;在你的情况下可能是-1?

于 2010-06-27T19:36:26.397 回答
0

您从中移动数据的对象可能不是临时对象(例如,您可以使用 std::move ) - 让您的对象处于无效状态是不好的形式。

于 2010-06-27T19:43:15.553 回答
0

显然,程序员决定长度应该总是有一个正确的值。如果不设置,析构函数中的代码将不再打印正确的内容:

std::cout << "In ~MemoryBlock(). length = "
                << _length << ".";
于 2010-06-27T17:06:15.913 回答
0

_length并且_data是语义相关的项目。对于处于一致状态的对象,_length应始终告诉您 . 指向的块中有多少内存_data。当_data指向 100 个块时,_length应该是 100。当_data指向 1 个块时,_length应该是 1。如果_data不指向任何东西(NULL),那么_length应该是 0。否则,如果_data是 NULL 并且_length是 100,那么你的对象在不一致的状态。当我做:

for (int i = 0; i < _length; ++i)
{
  // do something with _data[i], such as:
  _data[i] = 0;
}

我不应该崩溃。如果设置不_length正确,会崩溃。真正的问题是,为什么要故意让对象处于不一致的状态,从而导致崩溃?

于 2010-06-27T17:55:43.057 回答