Создание не копируемых, но подвижных объектов в c ++ - PullRequest
9 голосов
/ 23 ноября 2010

Просто вопрос.Глядя на библиотеки C ++ Boost (в частности, класс boost :: thread), я подумал: «Как создать класс, определяющий объекты, которые нельзя скопировать, но которые можно вернуть из функции?»

Хорошо рассмотрим этот пример, класс boost :: thread имеет характеристики, о которых я упоминал ранее, поэтому можно сделать это:

boost::thread make_thread();

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

Что ж, это означает, что объект boost :: thread не может быть скопирован, ноВернувшись из функции, это возможно.Как это возможно ????

Я предполагаю, что конструктор копирования не должен быть предоставлен, но как бороться с возвратом из функции?не нужно ли использовать конструктор копирования ???

Спасибо

Ответы [ 2 ]

5 голосов
/ 23 ноября 2010

Это будет возможно в C ++ 1x, который обеспечивает семантику перемещения через ссылки на rvalue. Используя это, вы можете реализовать перемещение и / или копирование отдельно:

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 даже при отсутствии семантики хода.

2 голосов
/ 23 ноября 2010

Это сложная тема C ++, если вы хотите сделать это в C ++ 03. См. Howard Hinnants Unique_ptr C ++ 03 эмуляция для примера этого.

В основном он работает, используя несколько тонких правил в разрешении перегрузки C ++, в частности правило, что неконстантные ссылки не могут связываться с временными значениями rval и что неконстантные функции преобразования все еще могут вызываться для неконстантных временных значений.

Вы также можете использовать технику auto_ptr, применяемую в C ++ 03, которая, тем не менее, рассматривается как нарушенная несколькими группами, поскольку auto_ptr позволяет копировать переменные, но красть ресурсы из объекта скопированного объекта (другие группы придерживаются другого мнения о это).

...