2010-11-23 14 views
8

Solo 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?"Creación de objetos no copiables, pero movibles, en C++

pozo considera este ejemplo, la clase de impulso :: hilo tiene las características que he mencionado antes, 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 impulso :: hilo objeto no se puede copiar , pero regresó de una función, esto es posible. ¿Cómo es esto posible ???

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

Gracias

Respuesta

4

Esto será posible en C++ 1x, que proporciona mover la semántica a través de referencias rvalue. El uso de este se puede implementar en movimiento y/o copia separadamente:

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 pueden ser prohibidas por separado, de modo que pueda clases de instalación que se pueden mover, pero no se han copiado.

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

+0

¿Qué es C++ 1x? Puedo ver c1x y C++ 0x en Internet, pero no C++ 1x. ¿Es taquigrafía para los dos? –

+1

@Alex - es inteligente decir que ya es 2010 y no se han lanzado. Hay un contador más inteligente: 0x es hexadecimal. –

+0

@Alex: Solía ​​llamarse C++ 0x, porque se esperaba antes de 2010, pero esto no funcionó. Muchos todavía se apegan a "C++ 0x", aunque es probable que termine como C++ 11 o C++ 12. – sbi

2

Este es un tema avanzado de C++ si desea hacer esto en C++ 03. Ver Howard Hinnants Unique_ptr C++03 emulation 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 se pueden vincular a las temporarias rvalue y que las funciones de conversión no const pueden aún invocarse en temporales no const.

También puede utilizar 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).