Notre page Facebook | |
Notre groupe Facebook |
|_Accueil Langage C++
|_RAII et les « smart pointers »
|_Mise en oeuvre d'une classe de « smart pointers »
|_Utilisation de la classe std::unique_ptr
|_Utilisation de la classe std::shared_ptr
|_Gestion des cycles de « smart pointers »
|_Application de RAII à la gestion des Mutex
Accès rapide :
Présentation de la classe
Exemple d'utilisation de la classe
Les classes de pointeurs malins (smart pointers) fournies en standard dans la librairie C++ sont accessible via
l'entête <memory>
. C'est notamment le cas de la classe std::unique_ptr
.
Il est néanmoins à noter que cette classe est disponible depuis la version 2011 du standard C++
(l'option -std=c++11
est donc requise pour compiler avec g++).
La classe std::unique_ptr
respecte le principe RAII (Resource Acquisition Is Initialization - voir
la page d'introduction à ce chapitre à ce sujet) en
garantissant que la durée de vie de votre pointeur et de la zone de mémoire associée sont liés à la durée de
vie de l'instance de pointeur malin. Dés que celui-ci disparait, la zone de mémoire est automatiquement relachée.
Par contre, comme son nom l'indique, l'association entre le pointeur sur la ressource à relâcher et l'instance de
type std::unique_ptr
est unique. Les instances de type std::unique_ptr
ne pourront donc
pas être dupliquées (contrairement à des instances de types std::shared_ptr
).
Remarque : cette classe provient du projet Boost.
Son nom originel était boost::scoped_ptr
. Cette information est importante pour ceux qui souhaiteraient
utiliser cette classe avec une chaine de compilation antérieur au standard C++11.
Reprenons notre classe de ressources vu dans la page précédente. En revoici, a titre de rappel, la déclaration et l'implémentation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#ifndef __RESOURCE #define __RESOURCE #include <memory> #include <string> class Resource { std::string name; public: Resource( const std::string & name ); ~Resource(); void doSomething(); }; typedef std::unique_ptr< Resource > ResourcePtr; #endif |
Notez la définition du typedef
afin de simplifier l'utilisation de la classe de pointeurs malins.
Et voici maintenant le fichier d'implémentation de notre classe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <iostream> using namespace std; #include "Resource.h" Resource::Resource( const std::string & name ) : name( name ) { cout << "Resource " << name << " created" << endl; } Resource::~Resource() { cout << "Resource " << name << " released" << endl; } void Resource::doSomething() { cout << "Resource " << name << " used" << endl; } |
Et voici maintenant un exemple d'utilisation de notre classe de ressource au travers de pointeurs malins de type
std::unique_ptr
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <iostream> using namespace std; #include "Resource.h" int main(int argc, char * argv[]) { ResourcePtr ptr1( new Resource( "Demo" ) ); ptr1->doSomething(); // Les lignes de code suivantes ne compilent pas /* ResourcePtr ptr2; // Basé sur nullptr ptr2 = ptr1; // Copie impossible ResourcePtr ptr3( ptr1 ); // Copie impossible */ return 0; } |
Compilons maintenant notre programme et lançons-le.
$> g++ -std=c++14 *.cpp -o raii $> raii Resource Demo created Resource Demo used Resource Demo released $>
Si vous tentez de compiler les lignes commentées vous produirez les messages d'erreurs suivants :
$> g++ -std=c++14 *.cpp -o raii UseResource.cpp: Dans la fonction 'int main(int, char**)': UseResource.cpp:17:10: erreur: use of deleted function 'std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=( const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Resource; _Dp = std::default_delete<Resource>]' ptr2 = ptr1; // Copie impossible ^ In file included from /usr/include/c++/5.3.1/memory:81:0, from Resource.h:4, from UseResource.cpp:5: /usr/include/c++/5.3.1/bits/unique_ptr.h:357:19: note: declared here unique_ptr& operator=(const unique_ptr&) = delete; ^ UseResource.cpp:19:28: erreur: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Resource; _Dp = std::default_delete<Resource>]' ResourcePtr ptr3( ptr1 ); // Copie impossible ^ In file included from /usr/include/c++/5.3.1/memory:81:0, from Resource.h:4, from UseResource.cpp:5: /usr/include/c++/5.3.1/bits/unique_ptr.h:356:7: note: declared here unique_ptr(const unique_ptr&) = delete; ^ $>
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :