有没有必要在c ++ 11中定义只移动对象?

Gov*_*van 8 c++ smart-pointers std pass-by-value c++11

我之前有一个关于使用unique-ptrs的问题.我得到这个答案,建议使用仅移动对象.我定义了一个类如下:

class B {
    const string objName;
public:

    B ( B && ) = default;
    B &  operator= ( B && ) = default;
    B ( const B & ) = delete;
    B & operator= ( const B & ) = delete;

    B(const string & name) :
            objName(name) {

    }

    virtual ~B();

    const string name() const { return objName;};
}
Run Code Online (Sandbox Code Playgroud)

我用这句话打电话给B:

class A {
A(){}
void take(B b);
}

A a; 
B b("test");
cout<<b.name();
a.take(std::move(b));
cout<<b.name();
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 即使我已经默认了移动构造函数,我也不能写a.take(b)并且我正在编译错误.我理解复制constrctor已被删除但似乎逻辑选择是在默认情况下使用move构造函数而不需要像这样编写std :: move a.take(b)
  2. 在结果中,"测试"被打印两次.调用move后为什么没有删除b对象?如果b对象仍然存在并且它的副本已经发送到a.take(move(b))那么这意味着我们没有使用rvalue对象的move.
  3. 如上所述使用仅移动对象是一个好习惯(删除复制构造函数和赋值运算符以及默认移动构造函数和移动赋值)?

twe*_*eej 5

是的,有一点.管理在对象之间不能/不应该共享的资源(可能是物理的)的对象是第一个想到的例子.

1)你写错了.基于这个问题和你之前的问题,我认为你想要的是这个.

class B {
    std::string objName;
public:
    B ( B && ) = default;
    B &  operator= ( B && ) = default;
    B ( const B & ) = delete;
    B & operator= ( const B & ) = delete;
    B(const std::string & name) :
            objName(name) {}
    virtual ~B() {}
    std::string name() const { return objName;}
};

class A {
public:
   std::vector<B> v;
   void take(B && b)
   {
      v.push_back(std::move(b));
   }
};

int main()
{
   A a;
   B b("test");

   std::cout << "Before: " << b.name() << std::endl;
   a.take(std::move(b));
   std::cout << "After: " << b.name() << std::endl;

   std::cout << "A has elements: " << std::endl;
   for(B &b : a.v)
      std::cout << "  " << b.name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

2)您正在访问已移动的值,这没有任何意义!这个答案已经很好地解释了,但是下面我还包括了std :: move的STL参考文本.

http://en.cppreference.com/w/cpp/utility/move

除非另行指定,否则已移出的所有标准库对象都将处于有效但未指定的状态.也就是说,只有没有前置条件的函数(例如赋值运算符)才能在对象移动后安全地使用.

3)根据我的经验,我发现了两种合法用途.在这两种情况下,仅移动对象控制物理资源,如果由两个对象共享将破坏一切.

  • 请注意,无需显式删除copy ctor和assignment运算符.用户定义的移动语法禁用复制,请参阅例如实例[此处](http://coliru.stacked-crooked.com/a/d20de6c4f219a22e). (2认同)