C++ 为什么';移动一个对象不会让它为空吗?

C++ 为什么';移动一个对象不会让它为空吗?,c++,c++11,move-semantics,C++,C++11,Move Semantics,移动后,a1的成员变量设置为默认值,而a1本身未设置为null。您不能执行a1==nullptr。。。要检查a1是否无用 我觉得这很奇怪。我有什么误解吗?我认为,如果a1被移动,它将变得无用,这应该通过以某种方式将其设置为null来表示。没有 问题是,通过让a1保持非空状态,它仍然可以使用。没有编译器警告或错误。没有真正的迹象表明该对象处于混乱状态。如果a有两个成员变量,一个int和一个dynamicalloc对象,那么dyn alloc对象将指向nullptr,但int将有一个def值(当然,

移动后,a1的成员变量设置为默认值,而a1本身未设置为null。您不能执行a1==nullptr。。。要检查a1是否无用

我觉得这很奇怪。我有什么误解吗?我认为,如果a1被移动,它将变得无用,这应该通过以某种方式将其设置为null来表示。没有

问题是,通过让a1保持非空状态,它仍然可以使用。没有编译器警告或错误。没有真正的迹象表明该对象处于混乱状态。如果a有两个成员变量,一个int和一个dynamicalloc对象,那么dyn alloc对象将指向nullptr,但int将有一个def值(当然,只有在正确实现的情况下……很容易出错)

所以搬家后你可以

A a5(move(a1));
并获取一个未意识到a1已重置的数字。在C和C++中,当资源被窃取以消除这种混乱时,我们被教导将指针设置为null(A.K.NulLPTR或NULL)。随着移动盗取对象资源的引入,是否没有内置机制或最佳实践来指示对象被盗取,从而将“重置”为默认构造状态

编辑 增加了样品移动器

int number = a1.getInt();

移动操作的结果应该使对象保持有效但未指定的状态。通常,如果要销毁对象或为对象指定新值,您会移动。您通常不会在移出对象后尝试使用该对象

a1类型的移动构造函数负责执行移动,并使对象保持您希望的状态。如果默认生成的移动构造函数的行为不符合您的要求,则可以为对象编写自己的移动构造函数。例如,您可以在此移动构造函数中将指针设置为null。或者,您可以设置一个标志,指示对象处于“从移动”状态

在您的问题中,您“希望”的行为更像是与空对象交换的行为。也许以下代码更适合您:

A(A&& other) : num(other.num), s(other.s){
   other.num = 0;
   other.s = nullptr;     //dyn alloc obj
}

关于建议
other.s
指向“dyn alloc obj”的更新:您应该避免这样做,因为这意味着您必须浪费时间编写复制构造函数、移动构造函数、复制赋值操作符、移动赋值操作符和析构函数

在这里,你是你自己死亡的建筑师:通过将这个指针引入你的类,你就产生了你所抱怨的移动问题

相反,任何拥有的资源都应该由它自己的类管理。标准库的
std::unique_ptr
足以满足许多这样的用例

为什么移动一个对象不使其为空

因为如果对象不是指针,那么它通常不具有“null状态”,因此不能“保持null”;如果它是一个指针,当你“移动”它时,你不会使它为空

让a1处于非空状态,它仍然可以使用。没有编译器警告或错误。没有真正的迹象表明该对象处于混乱状态


它不是在一个混乱的状态,它是在一个混乱的状态。但是,当您使用“移动自”对象的“移动后”值时,出现警告可能不是一个坏主意。

C++没有像其他语言一样将对象设置为“null”的通用方法。通常,代码>移动< /CONT> ING对象将复制或保留它处于“空”状态,但完全取决于实现“NULL”不是C++中的一般事情。移动操作的要求是将对象置于有效但未指定的状态,该状态可能被安全破坏。没有要求它将对象保持在“空”或“空”状态。因此,是否没有办法知道或检查对象是否被窃取?我还认为有一些警告或检查是一个好主意。但显然,要么人们不理解这个问题,要么认为考虑到否决票,这不是一个好主意。你难道不喜欢人们在没有任何解释的情况下投反对票吗?@code:在我看来,StackOverflow上有一种可怕的反对票文化。人们出于各种不相关的原因否决了你的投票,而不是因为你的气馁;因为你误解了一些事情(这就是提问的意义所在);等等还有,请看。话虽如此——你的问题措辞有点拙劣——你没有解释A和a1的来源等。谢谢,虽然我同意你在这里所说的,我已经知道了。恕我直言,这不是我要问的。我在问是否有办法知道或检查某个对象是否被盗?@code您的问题标题是“为什么移动对象时不保留空值?”,而不是“如何知道对象是否已从中移动?”。我在回答的另一个问题的部分加了粗体。谢谢,M.M.也许标题不太理想,但如果你读到它,整个问题都是关于由于无法识别被盗对象而导致的潜在未命中使用后移动操作。@code是的,我在回答中提到了这一点,并解释了你应该做什么
A a5{};
using std::swap;
swap(a5, a1);