C++11 有没有办法制作一个移动的对象;无效;?

C++11 有没有办法制作一个移动的对象;无效;?,c++11,move,move-semantics,C++11,Move,Move Semantics,我有一些将一个对象移动到另一个对象的代码。我将不再需要原来的,移动的对象在更高的水平。因此,我认为搬家是正确的选择 然而,考虑到安全性,我想知道是否有一种方法可以使移动的对象无效,从而防止在有人访问它时出现未定义的行为 这是一个很好的例子: // move example #include <utility> // std::move #include <vector> // std::vector #include <string>

我有一些将一个对象移动到另一个对象的代码。我将不再需要原来的,移动的对象在更高的水平。因此,我认为搬家是正确的选择

然而,考虑到安全性,我想知道是否有一种方法可以使移动的对象无效,从而防止在有人访问它时出现未定义的行为

这是一个很好的例子:

// move example
#include <utility>      // std::move
#include <vector>       // std::vector
#include <string>       // std::string

int main () {
  std::string foo = "foo-string";
  std::string bar = "bar-string";
  std::vector<std::string> myvector;

  myvector.push_back (foo);                    // copies
  myvector.push_back (std::move(bar));         // moves

  return 0;
}

编辑:如果没有这样的事情,为什么

移动语义就是这样工作的,这样你就可以得到一个处于正确状态的对象。正确的状态意味着所有字段都有正确的值,并且所有内部不变量仍然良好。之所以这样做,是因为在移动之后,您实际上并不关心移动对象的内容,但资源管理、分配和析构函数之类的东西应该可以正常工作。 所有STL类(以及所有使用默认移动构造函数/赋值进行分类的类)只需将其内容与新的内容交换,因此这两种状态都是正确的,并且非常容易实现、快速和方便

您可以定义您的类,该类的
isValid
字段通常为true,并且在移动中(即在移动构造函数/移动赋值中)将其设置为false。然后,您的对象将具有“正确”状态“我无效”。只是别忘了在需要的地方检查它(析构函数、赋值等)

isValid
字段可以是一个具有空值的指针。关键是:你知道,对象在移动后处于可预测的状态,而不仅仅是内存中的随机字节

编辑:
字符串的示例

class String {
public:
    string data;
private:
    bool m_isValid;

public:
    String(string const& b): data(b.data), isValid(true) {}

    String(String &&b): data(move(b.data)) {
        b.m_isValid = false;
    }

    String const& operator =(String &&b) {
        data = move(b.data);
        b.m_isValid = false;
        return &this;
    }

    bool isValid() {
        return m_isValid;
    }
}

访问移动的对象不是未定义的行为。移动的对象仍然是有效的对象,并且程序很可能希望继续使用所述对象。比如说,

template< typename T >
void swap_by_move(T &a, T &b)
{
    using std::move;
    T c = move(b);
    b = move(a);
    a = move(c);
}
模板
通过移动无效掉期(T&a、T&b)
{
使用std::move;
tc=移动(b);
b=移动(a);
a=移动(c);
}

更大的答案是因为移动或不移动是在运行时做出的决定,而给出编译时错误是在编译时做出的决定

foo(bar); // foo might move or not
bar.baz(); // compile time error or not?
这是行不通的。。您可以在编译时分析中使用近似值,但是对于开发人员来说,要想保持一个有效的程序不出错或做任何有用的事情都是非常困难的,或者开发人员必须对调用的函数进行恼人且脆弱的注释,以保证不移动参数


换言之,如果使用包含值42的整数变量,则会出现编译时错误。或者,如果使用的指针包含空指针值。在使用分析API的CLAN实现一个近似的编译时代码约定检查程序时,您可能会成功,但是,如果C++不能执行C++的AST,如果不能证明“代码> STD::移动< /代码>直到某个变量的使用,就不能调用。”如果你还想使用初始化的内存,那就好了。然而,问题是关于我不想再使用它的情况,事实上我想使它完全无效。
foo(bar); // foo might move or not
bar.baz(); // compile time error or not?