【问题标题】:This move constructor of Microsoft example appears to have redundant codeMicrosoft 示例的此移动构造函数似乎有冗余代码
【发布时间】:2017-12-05 06:58:24
【问题描述】:

开发者的MSDN page有这个代码sn-p:

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

   // Copy the data pointer and its length from source object.  
   _data = other._data;      // Assginment 1
   _length = other._length;  // Assignment 2

   // 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;  
}

当标记为Assignment 1Assignment 2的指令覆盖_data和@987654326的值时,_data(nullptr)_length(0)有什么用@?

【问题讨论】:

  • “内存初始化”是什么意思?
  • 好习惯比纳米优化更有价值。
  • @juanchopanza 在看到构造函数的左大括号之前初始化成员变量时。我不记得确切的参考,但是这个术语(mem-initializer)在流行的 C++ 文献之一中使用。内存初始化是早期 C++ 版本允许 const 和引用成员初始化的唯一方式。
  • 此外,此代码调用可能引发异常的方法,这对于移动构造函数来说是一种不好的做法。
  • @SeshadriR 是的,我不认为这叫做“内存初始化”。反正代码看起来挺多余的。

标签: c++ c++11 move-constructor


【解决方案1】:

应该是这样的

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

   // 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;  
}  

【讨论】:

    【解决方案2】:

    为了安全。

    假设由于某种原因,other._data 和/或other._length 无法访问它们的值(很可能是指针other._data)。

    一个例子可能是指针指向无效内存并产生分段错误(因为您可能访问不属于您的程序的内存),并且程序在该点崩溃。另一种可能是other*nullptr,等等……那么_data_length 的值是多少?未定义。

    这两个有它们的初始值会很好,因为这可能有助于调试,因为程序员可以认为既然这两个有它们的初始值,那么赋值可能有问题。

    【讨论】:

    • 当您说“指针无效”时,您的意思是在Window上分配时检查指针值的有效性?
    • other 可能是*nullptr,因此other._data 可能会崩溃
    • @Oliv 我说的是指向无效内存的指针。
    • @gsamaras,如果other 是一个悬空引用,取消引用它可能会产生处理器异常,但这不是进程终止的唯一可能原因吗?
    • @pqnet 如果other 是一个空-引用,那么代码就已经牢牢地在UB 领域内。事后没有办法解决这个问题。就C++标准而言,没有空引用这种东西,所以other的成员访问必须成功。如果 other 作为指针传递,则此答案有效,但此处并非如此。
    猜你喜欢
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2019-05-22
    • 1970-01-01
    相关资源
    最近更新 更多