为什么 std::move 不将默认移动构造函数中的源变量更改为默认值?
Why std::move don't change source variable to default value in default move constructor?
我试图理解移动构造函数。
我在类的构造函数中分配内存,并在析构函数中销毁它。
当我尝试移动班级时,我仍然有双倍免费。
#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 如何使原始变量的值无效?
C++如何将对象移动到空点
C++ std::移动指针
std::move
只生成一个右值(xvalue(;它不会执行移动操作,根本不会修改参数。
特别是,
std::move
生成一个 xvalue 表达式,用于标识其参数t
。它完全等效于右值引用类型的static_cast
。
给定this->a_ = std::move(other.a_);
,作为内置类型,即int*
,this->a_
只是从ohter.a_
复制赋值,那么两个指针都指向同一个对象。默认的移动构造函数实际上执行相同的操作。(它对数据成员执行成员级移动操作;请注意,对于内置类型,移动的效果与复制效果相同。
如果要定义移动后对象应包含 null 指针,则需要将other.a_
设置为显式nullptr
。
例如
TestClass(TestClass && other) noexcept
{
this->a_ = other.a_;
other.a_ = nullptr;
}
首先,std::move
只是一个强制转换,导致other.a_
被视为右值。对于指针,移动只是一个副本。
我认为是这样,因为并非在所有情况下都需要清除源指针,并且在不需要的情况下会导致开销。
您需要明确地进行清理。
或者,更简单,只需使用std::unique_ptr<int> a_
.然后,您无需定义任何特殊成员函数,并且该类的行为与您想象的一样。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- Makefile g++ 使用命令行中的 -D 变量进行编译,默认值
- 变量始终在函数中重置为默认值
- 为什么 std::move 不将默认移动构造函数中的源变量更改为默认值?
- 如果输入类型与目标类型不同,"cin"变量是否重置为某个默认值?
- C++中未初始化成员布尔变量的默认值是多少?
- char指针或char变量的默认值是多少
- const变量是否可以在具有默认值的参数中赋值(作为可选参数)
- 变量不能在 lambda 中隐式捕获,并且没有使用 switch 语句指定捕获默认值
- 从不使用 C/C++ 默认值/分配给变量的值
- 模板类专业化具有成员变量和方法的默认值
- 使用Boost Spirit将默认值分配给变量
- 如何将结构变量初始化为默认值
- 为构造函数初始化引用实例变量提供默认值
- 是初始化为其默认值的外部变量
- 变量始终具有默认值,而不是我计算的值
- 是否可以将`constexpr`模板变量作为正式模板参数的默认值
- 如何使用命名变量定义常量右值引用参数的默认值
- enum变量的默认值是什么
- 为构造函数中的变量设置默认值