在c ++中创建不可复制但可移动的对象

时间:2010-11-23 19:50:50

标签: c++ boost object noncopyable movable

只是一个问题。看看C ++ Boost库(特别是boost :: thread类)我最后想到:“如何创建一个定义无法复制但可以从函数返回的对象的类?”

考虑一下这个例子,boost :: thread类具有我之前提到的特性,所以可以这样做:

boost::thread make_thread();

void f()
{
    boost::thread some_thread=make_thread();
    some_thread.join();
}

这意味着对象boost :: thread无法复制,但是从函数返回,这是可能的。 怎么可能????

我认为不能提供复制构造函数,但是如何处理函数返回?它不需要使用复制构造函数???

三江源

2 个答案:

答案 0 :(得分:5)

这可以在C ++ 1x中实现,它通过右值引用提供移动语义。使用它可以分别实现移动和/或复制:

class my_class {
  private:
    data_t* data_;
  public:
    my_class(const my_class& rhs)      // copy constructor
     : data_(rhs.data_.clone())
    {}
    my_class(my_class&& rhs)           // move constructor
     : data_(rhs.data_)
    {
      rhs.data_ = NULL;
    }
    ~my_class() {delete data_;}        // noop if data_==NULL

    my_class& operator=(my_class rhs)  // copy assignment
    {
      this->swap(rhs);
    }
    my_class& operator=(my_class&& rhs)// move assignment
    {
      this->swap(rhs);
    }

    // ...
};

可以单独禁止复制和移动,因此您可以设置可以移动但不能复制的类。

当然,有一些神奇的技巧可以让你这样做,即使你的编译器还没有支持移动语义(std::auto_ptr,所有移动而不是分配时复制),所以这可能工作对于boost::thread,即使没有移动语义。

答案 1 :(得分:2)

如果您想在C ++ 03中执行此操作,这是C ++的高级主题。有关示例,请参阅Howard Hinnants Unique_ptr C++03 emulation

它基本上是通过滥用C ++重载决策中的几个细微规则来工作的,特别是非const引用不能绑定到右值临时值的规则,并且非const转换函数仍然可以在非const临时值上调用。

您也可以使用C ++ 03使用的auto_ptr技术,但是由于auto_ptr允许您复制变量,但是从复制的对象中窃取资源(其他组有其他组的意见)这一点)。