C++ 为什么std::移动don';是否在默认移动构造函数中将源变量更改为默认值?

C++ 为什么std::移动don';是否在默认移动构造函数中将源变量更改为默认值?,c++,c++11,move-semantics,stdmove,C++,C++11,Move Semantics,Stdmove,我试图理解move构造函数 我在类的构造函数中分配内存,并在析构函数中销毁它 当我尝试移动班级时,我仍然有一个双人自由 #include <algorithm> class TestClass { public: TestClass() {a_ = new int[1];} TestClass(TestClass const& other) = delete; TestClass(TestClass && other) noexcept //

我试图理解move构造函数

我在类的构造函数中分配内存,并在析构函数中销毁它

当我尝试移动班级时,我仍然有一个双人自由

#include <algorithm>

class TestClass
{
 public:
  TestClass() {a_ = new int[1];}
  TestClass(TestClass const& other) = delete;
  TestClass(TestClass && other) noexcept // = default;
  {
    this->a_ = std::move(other.a_);
  }
  ~TestClass() {delete[] a_;}
 private:
  int* a_ = nullptr;
};

int main( int argc, char** argv )
{
  TestClass t;
  TestClass t2 = std::move(t);
}
#包括

只产生一个右值(xvalue);它不会执行移动操作,根本不会修改参数

特别是,
std::move
生成一个xvalue表达式,用于标识其参数
t
。它完全等同于对右值引用类型的
static\u cast

给定
this->a\ux=std::move(other.a\ux)
,作为内置类型,即,
int*
此->a
只是从
ohter.a
复制赋值,然后两个指针指向同一个对象。默认的move构造函数实际上做了同样的事情。(它对数据成员执行成员移动操作;请注意,对于内置类型,移动的效果与复制相同。)

如果要定义移动后对象应包含空指针,则需要显式地将
other.a
设置为
nullptr

例如


首先,
std::move
只是一个cast,它导致将
other.a_
视为右值。对于指针来说,移动只是一个拷贝

我认为这是因为在所有情况下都不需要清除源指针,在不需要的情况下会导致开销

您需要明确地进行清除


或者,更简单的是,只需使用
std::unique\u ptr a
。然后您不需要定义任何特殊的成员函数,类的行为与您想象的一样。

在您的移动构造函数中,您忘记了
other.a_979;=nullptr。或者通过执行
std::swap(this_>a_uu,other.a_uu)。在C++14及之后,您将使用初始化
a
我假设这是某种培训,这就是为什么您不使用
std::vector
的原因,它将以最好的方式完成此操作。是的,它是一个POC。我想了解移动构造函数/赋值的默认实现是什么,并想知道何时需要使用默认或自定义实现。@VincentLEGARREC
std::move()
只是一个类型转换,您试图“移动”到原始指针,而不是带有移动构造函数或移动赋值运算符的移动类型。这实际上是一个拷贝分配,因此没有调用任何代码来将输入指针重置为
nullptr
。谢谢。那么,默认复制构造函数和默认移动构造函数(除了一个使用const ref,另一个使用非const rvalue)之间有什么区别呢?@VincentleGarrc对于内置类型的数据成员,它们具有相同的效果。两个类类型的数据成员都将调用数据成员上的复制构造函数或移动构造函数,然后效果取决于数据成员的构造函数是如何实现的。
TestClass(TestClass && other) noexcept
{
  this->a_ = other.a_;
  other.a_ = nullptr;
}