Pointeur intelligent ✱
Nous vous avons conseillé d’utiliser la classe vector de la STL pour gérer les allocations mémoire dynamique (principe RC0). Ainsi, lorsque vous voulez faire une liste d’objets de type A, aucun soucis, la classe vector convient et suffit amplement. Alors pourquoi parler des pointeurs ? A cause de l’héritage ! En effet, si vous voulez faire une liste d’objets appartenant à une même hiérarchie, alors le C++ ne saura pas gérer ! Prenons un exemple : supposons que nous ayons une classe mère A et deux classes filles B et C. Pour créer un container pouvant stocker des objets de type A, B ou C, il va falloir choisir un type comme argument du template vector. On choisira donc naturellement la classe mère de la hiérarchie et on déclarera un vector<A>. Malheureusement, en C++, cette syntaxe sous-entend que tous les objets dans ce container ne peuvent être QUE du type A. Impossible alors de stocker des objets de type B ou C. Pourquoi ? Rappelons que même si B et C sont des enfants de A, ils ne prennent pas forcément la même place en mémoire car ils peuvent stocker des informations supplémentaires. Or, un vector<A>, qui est en fait comme un tableau de A : A[], ne peut malheureusement stocker que des objets de même taille, d’où le problème. Pour sortir de l’impasse, on devra utiliser un vector de pointeurs vers des objets de type A et la mécanique interne du C++ va nous garantir qu’elle sera capable de déterminer le type exact : A, B ou C, de l’objet désigné par chaque pointeur. Bref, on ne peut pas enterrer l’utilisation des pointeurs dans le C++ moderne, sauf si vous n’utilisez pas l’héritage ! Cependant, dans un soucis de modernité, on va utiliser des smart pointeurs alliant la rapidité du C++ à la sécurité d’un garbage collector présent dans les autres langages comme Java ou C#.
Quizzz
Donnez la syntaxe pour créer un shared pointer sur un objet de type T construit avec les paramètres 3 et 5 (sans ;).
Depuis un shared pointer p, pour accéder au paramètre a, dois-je écrire p.a ?
Quelle est la valeur affichée par le code suivant :
void test(shared_ptr<Point> p) { p->Aff(); } int main() { shared_ptr<Point> p = make_shared<Point>(1,2); for (int i = 0 ; i < 3 ; i++) test(p); cout << p.use_count(); return 0; }
Lorsque deux objets forment une dépendance cyclique, lorsqu’ils ne seront plus utilisés par le programme, l’utilisation de shared pointer permet de libérer ces objets contrairement aux pointeurs classiques.