11

就一个问题。看着 C++ Boost 库(特别是 boost::thread 类),我最终想到:“如何创建一个定义对象的类,这些对象不能被复制但可以从函数中返回?”

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

boost::thread make_thread();

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

那么这意味着对象 boost::thread 不能被复制,而是从函数返回,这是可能的。这怎么可能????

我想一定不能提供复制构造函数,但是如何处理从函数返回?它不需要使用复制构造函数吗???

谢谢

4

2 回答 2

6

这在 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即使没有移动语义,这也可能适用.

于 2010-11-23T19:53:00.257 回答
2

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

它基本上是通过在 C++ 重载决议中滥用一些微妙的规则来工作的,特别是非常量引用不能绑定到右值临时对象以及仍然可以在非常量临时对象上调用非常量转换函数的规则。

您还可以使用 C++03 所采用的 auto_ptr 技术,但该技术已被多个小组所破坏,因为 auto_ptr 允许您复制变量,但从复制的对象中窃取资源(其他小组对此有其他意见)。

于 2010-11-23T19:54:15.267 回答