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

发布于 2024-10-04 05:11:10 字数 394 浏览 5 评论 0原文

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

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

boost::thread make_thread();

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

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

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

谢谢

Just a question. Looking at C++ Boost libraries (in particular boost::thread class) I ended up thinking: "how is it possible to create a class defining objects that cannot be copied but that can be returned from a function?"

Well consider this example, the boost::thread class has the characteristics I mentioned before, so it is possible to do this:

boost::thread make_thread();

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

Well this means that the object boost::thread cannot be copied, but returned from a function, this is possible.
How is this possible????

I suppose that a copy constructor must not be provided, but how to deal with returning from a function? doesn't it need to use a copy constructor???

Thankyou

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只有一腔孤勇 2024-10-11 05:11:11

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

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

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

This is an advanced topic of C++ if you want to do this in C++03. See Howard Hinnants Unique_ptr C++03 emulation for an example of that.

It basically works by abusing several subtle rules in C++ overload resolution, in particular the rule that non-const references cannot bind to rvalue temporaries and that non-const conversion functions can still be called on non-const temporaries.

You can also use the auto_ptr technique as employed by C++03, which however is seen as broken by several groups because auto_ptr lets you copy variables, but steal resources from the copied-from object (other groups have other opinions about this).

ˇ宁静的妩媚 2024-10-11 05:11:10

从 C++11 开始,这是可能的,它通过右值引用提供移动语义。使用此功能,您可以单独实现移动和/或复制:

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 。

This is possible starting with C++11, which provides move semantics via rvalue references. Using this you can implement moving and/or copying separatedly:

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);
    }

    // ...
};

Copying and moving can be forbidden separately, so you can setup classes that can be moved, but not copied.

Of course, there are a few magical tricks that let you do this even when your compiler doesn't yet support move semantics (std::auto_ptr, after all moves instead of copying when assigned to), so this might work for boost::thread even in the absence of move semantics.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文