Pregunta Crear objetos no copiables, pero movibles, en c ++


Sólo una pregunta. En cuanto a las bibliotecas de C ++ Boost (en particular boost :: clase de hilo) terminé pensando: "¿cómo es posible crear una clase que defina objetos que no se pueden copiar pero que se pueden devolver desde una función?"

Considere este ejemplo, la clase boost :: thread tiene las características que mencioné anteriormente, por lo que es posible hacer esto:

boost::thread make_thread();

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

Bueno, esto significa que el objeto boost :: thread no se puede copiar, sino que se devuelve desde una función, esto es posible. ¿¿¿¿Cómo es esto posible????

Supongo que no se debe proporcionar un constructor de copia, sino cómo lidiar con el regreso de una función. ¿no necesita usar un constructor de copia?

Gracias


9
2017-11-23 19:50


origen


Respuestas:


Esto será posible en C ++ 1x, que proporciona semántica de movimiento a través de referencias rvalue. Al usar esto puede implementar mover y / o copiar por separado:

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

    // ...
};

Copiar y mover puede prohibirse por separado, por lo que puede configurar clases que se pueden mover, pero no copiar.

Por supuesto, hay algunos trucos mágicos que le permiten hacer esto incluso cuando su compilador aún no admite la semántica de movimientos (std::auto_ptr, después de todos los movimientos en lugar de copiar cuando se le asigna), entonces esto podría funcionar para boost::thread incluso en ausencia de semántica de movimiento.


5
2017-11-23 19:53



Este es un tema avanzado de C ++ si desea hacer esto en C ++ 03. Ver Emulación de Howard Hinnants Unique_ptr C ++ 03 para un ejemplo de eso.

Básicamente funciona abusando de varias reglas sutiles en la resolución de sobrecarga de C ++, en particular la regla de que las referencias no const no pueden vincularse a los valores temporales rvalue y que las funciones de conversión no const puedan aún invocarse en los temporales no const.

También puede usar la técnica auto_ptr empleada por C ++ 03, que sin embargo se considera rota por varios grupos porque auto_ptr le permite copiar variables, pero robar recursos del objeto copiado (otros grupos tienen otras opiniones sobre esto).


2
2017-11-23 19:54