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++ オーバーロードの解決におけるいくつかの微妙なルール、特に非 const 参照は右辺値一時変数にバインドできず、非 const 変換関数を非 const 一時変数で引き続き呼び出すことができるという規則を悪用することによって機能します。

C++03 で採用されている auto_ptr 手法を使用することもできますが、auto_ptr を使用すると変数をコピーできますが、コピー元のオブジェクトからリソースを盗むことができるため、いくつかのグループによって壊れていると見なされています (他のグループはこれについて別の意見を持っています)。

于 2010-11-23T19:54:15.267 に答える