2010-11-23 26 views
8

Juste une question. En regardant les bibliothèques C++ Boost (en particulier boost :: thread class) j'ai fini par penser: "comment est-il possible de créer une classe définissant des objets qui ne peuvent pas être copiés mais qui peuvent être retournés depuis une fonction?"Création d'objets non copiables mais mobiles en C++

bien considérer cet exemple, le boost :: classe thread a les caractéristiques je l'ai mentionné précédemment, il est donc possible de le faire:

boost::thread make_thread(); 

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

Eh bien, cela signifie que le coup de pouce d'objet :: thread ne peut pas être copié , mais renvoyé d'une fonction, c'est possible. Comment est-ce possible ????

Je suppose qu'un constructeur de copie ne doit pas être fourni, mais comment gérer le retour d'une fonction? n'a-t-il pas besoin d'utiliser un constructeur de copie ???

Thankyou

Répondre

4

Cela sera possible en C++ 1x, qui fournit la sémantique déplacer via des références rvalue. L'utilisation de ce que vous pouvez mettre en œuvre le déplacement et/ou la copie 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); 
    } 

    // ... 
}; 

copie et le déplacement peuvent être interdites séparément, afin que vous puissiez classes d'installation qui peuvent être déplacés, mais pas copiés.

Bien sûr, il y a quelques trucs magiques qui vous permettent de le faire même lorsque votre compilateur ne supporte pas encore la sémantique de mouvement (std::auto_ptr, après tous les mouvements au lieu de copier lorsqu'ils sont affectés à), donc cela pourrait fonctionner pour boost::thread même en l'absence de sémantique de mouvement.

+0

Qu'est-ce que C++ 1x? Je peux voir c1x et C++ 0x sur internet, mais pas C++ 1x. Est-ce un raccourci pour les deux? –

+1

@Alex - c'est smart-ass parler du fait que c'est déjà 2010 et qu'ils n'ont pas encore sorti. Il y a un compteur plus intelligent: 0x est hexadécimal. –

+0

@Alex: Il était appelé C++ 0x, car il était attendu avant 2010, mais cela n'a pas fonctionné. Beaucoup restent à "C++ 0x", même si cela finira probablement par C++ 11 ou C++ 12. – sbi

2

Ceci est un sujet avancé de C++ si vous voulez le faire en C++ 03. Voir Howard Hinnants Unique_ptr C++03 emulation pour un exemple de cela. Il fonctionne essentiellement en abusant de plusieurs règles subtiles dans la résolution de surcharge C++, en particulier la règle que les références non-const ne peuvent pas se lier aux rvalue temporaires et que les fonctions de conversion non-const peuvent toujours être appelées temporaires non-const. Vous pouvez également utiliser la technique auto_ptr telle qu'employée par C++ 03, mais qui est cependant considérée comme cassée par plusieurs groupes car auto_ptr vous permet de copier des variables, mais de voler des ressources à partir de l'objet copié (d'autres groupes ont d'autres opinions à propos de ça).