为什么 std::move 不在默认移动构造函数中将源变量更改为默认值?
Why std::move don't change source variable to default value in default move constructor?
我试着理解移动构造函数。
我在 class' 构造函数中分配内存并在析构函数中销毁它。
当我尝试移动 class 时,我仍然有双倍免费。
#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);
}
为什么std::move
不改成nullptrother.a_
?
如果移动构造函数是默认的,我也会遇到同样的问题。
我发现了以下问题,但我仍然不知道为什么移动运算符不将源变量更改为默认值。
std::move
只产生一个右值(xvalue);它不会执行移动操作,它根本不会修改参数。
In particular, std::move
produces an xvalue expression that identifies its argument t
. It is exactly equivalent to a static_cast
to an rvalue reference type.
给定 this->a_ = std::move(other.a_);
,作为内置类型,即 int*
,this->a_
只是从 ohter.a_
复制赋值的,那么两个指针都指向同一个目的。默认的移动构造函数实际上做同样的事情。 (它对数据成员执行逐成员移动操作;请注意,对于内置类型,移动的效果与复制相同。)
如果要定义移动后对象应包含空指针,则需要将 other.a_
显式设置为 nullptr
。
例如
TestClass(TestClass && other) noexcept
{
this->a_ = other.a_;
other.a_ = nullptr;
}
首先,std::move
只是一个导致 other.a_
被视为右值的转换。对于指针,移动只是复制。
我想是这样,因为在所有情况下都不需要清除源指针,并且在不需要的情况下会导致开销。
您需要明确地进行清理。
或者,更简单,只需使用 std::unique_ptr<int> a_
。然后你不需要定义任何特殊的成员函数并且 class 的行为就像你想象的那样。
我试着理解移动构造函数。
我在 class' 构造函数中分配内存并在析构函数中销毁它。
当我尝试移动 class 时,我仍然有双倍免费。
#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);
}
为什么std::move
不改成nullptrother.a_
?
如果移动构造函数是默认的,我也会遇到同样的问题。
我发现了以下问题,但我仍然不知道为什么移动运算符不将源变量更改为默认值。
std::move
只产生一个右值(xvalue);它不会执行移动操作,它根本不会修改参数。
In particular,
std::move
produces an xvalue expression that identifies its argumentt
. It is exactly equivalent to astatic_cast
to an rvalue reference type.
给定 this->a_ = std::move(other.a_);
,作为内置类型,即 int*
,this->a_
只是从 ohter.a_
复制赋值的,那么两个指针都指向同一个目的。默认的移动构造函数实际上做同样的事情。 (它对数据成员执行逐成员移动操作;请注意,对于内置类型,移动的效果与复制相同。)
如果要定义移动后对象应包含空指针,则需要将 other.a_
显式设置为 nullptr
。
例如
TestClass(TestClass && other) noexcept
{
this->a_ = other.a_;
other.a_ = nullptr;
}
首先,std::move
只是一个导致 other.a_
被视为右值的转换。对于指针,移动只是复制。
我想是这样,因为在所有情况下都不需要清除源指针,并且在不需要的情况下会导致开销。
您需要明确地进行清理。
或者,更简单,只需使用 std::unique_ptr<int> a_
。然后你不需要定义任何特殊的成员函数并且 class 的行为就像你想象的那样。