Pointeurs intelligents en C++
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy. Leçon 15 sur 104.
Les pointeurs intelligents sont des classes enveloppes qui gèrent automatiquement la mémoire du tas pour vous. Ils éliminent le besoin d’appels manuels à delete en libérant la mémoire lorsque le pointeur sort de sa portée.
Incluez l'en-tête <memory> pour utiliser des pointeurs intelligents.
unique_ptr - propriété exclusive. Un seul pointeur peut posséder la ressource à la fois.
#include <memory>
std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack(); // S'utilise comme un pointeur classique
// Impossible de copier, mais on peut transférer la propriété
std::unique_ptr<Player> player2 = std::move(player);
// player est maintenant nullptrshared_ptr - propriété partagée. Plusieurs pointeurs peuvent posséder la même ressource. La mémoire est libérée lorsque le dernier propriétaire est détruit.
std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1; // Les deux possèdent la ressource
std::cout << p1.use_count(); // Affiche 2weak_ptr - observateur non propriétaire d’un shared_ptr. Utile pour rompre les références circulaires.
std::shared_ptr<Player> shared = std::make_shared<Player>("Hero");
std::weak_ptr<Player> weak = shared;
if (auto locked = weak.lock()) { // Convertir en shared_ptr
locked->attack();
}Utilisez unique_ptr par défaut pour une propriété unique. Utilisez shared_ptr lorsque plusieurs objets doivent partager une ressource. Utilisez weak_ptr pour observer sans prolonger la durée de vie.
Préférez make_unique et make_shared à l'utilisation directe de new.
Défi
FacileConstruisons un système de partage de documents qui démontre les différents modèles de propriété des pointeurs intelligents. Tu verras comment unique_ptr impose une propriété exclusive, comment shared_ptr permet plusieurs propriétaires et comment weak_ptr peut observer sans affecter la durée de vie.
Tu vas créer deux fichiers pour organiser ton code :
Document.h: définir une classeDocumentqui représente un document partageable. Elle doit avoir :- Un attribut privé
title(chaîne de caractères) - Un constructeur qui prend un titre et affiche
"Document created: <title>" - Un destructeur qui affiche
"Document deleted: <title>" - Une méthode
getTitle()qui renvoie le titre
- Un attribut privé
main.cpp: démontrer les trois types de pointeurs intelligents en lisant un titre de document saisi, puis :- Créer un
unique_ptrvers un Document avec le titre saisi - Afficher
"Unique owner: <title>" - Transférer la propriété à un autre
unique_ptrà l’aide destd::move - Afficher
"Ownership transferred" - Créer un
shared_ptrvers un nouveau Document dont le titre est"SharedDoc" - Créer un deuxième
shared_ptrpointant vers le même document - Afficher
"Shared owners: <count>"à l’aide deuse_count() - Créer un
weak_ptrà partir de l’un des pointeurs partagés - Utiliser
lock()pour accéder au document via le pointeur faible et afficher"Weak access: <title>"
- Créer un
N’oublie pas d’inclure <memory> pour les pointeurs intelligents. Utilise std::make_unique et std::make_shared pour créer tes pointeurs intelligents. Les messages du destructeur t’aideront à voir quand chaque document est automatiquement nettoyé à la fin du programme.
Inclue ton fichier d’en-tête dans main.cpp à l’aide de #include "Document.h".
Essayez vous-même
#include <iostream>
#include <memory>
#include <string>
#include "Document.h"
using namespace std;
int main() {
string inputTitle;
cin >> inputTitle;
// TODO: Créer un unique_ptr vers un Document avec inputTitle
// en utilisant std::make_unique
// TODO: Afficher "Unique owner: <title>"
// TODO: Transférer la propriété à un autre unique_ptr en utilisant std::move
// TODO: Afficher "Ownership transferred"
// TODO: Créer un shared_ptr vers un nouveau Document avec le titre "SharedDoc"
// en utilisant std::make_shared
// TODO: Créer un second shared_ptr pointant vers le même document
// TODO: Afficher "Shared owners: <count>" en utilisant use_count()
// TODO: Créer un weak_ptr à partir de l'un des shared pointers
// TODO: Utiliser lock() pour accéder au document via le weak_ptr
// et afficher "Weak access: <title>"
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesGénération et compilation en C++Fichiers d’en-tête et fichiers sourceEspaces de noms et portéeIntroduction à la POO en C++Classes et objetsLe pointeur « this »Méthodes (fonctions membres)Attributs (membres de données)Bases des constructeurs et destructeursRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d’instance et statiquesAccesseurs et mutateursFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d’accès de l’héritageOrdre d’appel des constructeurs et destructeursRedéfinition des méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif : hiérarchie des employés10Vue d’ensemble de la STL
Vue d’ensemble et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - fréquence des mots13Modèles de conception, partie 1
Introduction aux modèles de conceptionModèle SingletonFabrique et fabrique abstraiteModèle BuilderModèle ObserverModèle Strategy2Gestion de la mémoire
Mémoire de pile ou de tasPointeurs et référencesMémoire dynamique (new/delete)Pointeurs intelligents en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d’accès en C++Spécificateurs d’accès en profondeurMasquage de l’informationStruct vs classeClasses imbriquées et internesRécapitulatif - Système de gestion des dossiers étudiants8Polymorphisme
Polymorphisme à la compilation vs à l’exécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d’interfaces en C++Conversion dynamique et RTTIRécapitulatif - Calculateur de formes3Constructeurs et destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d’initialisation des constructeursConstructeurs déléguésApprofondissement des destructeursRègle des trois / cinq / zéroRécapitulatif - Classe String6Surcharge des opérateurs
Introduction à la surcharge des opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l’opérateur d’affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif – Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation des templatesTemplates variadiquesBases de SFINAE et des traits de typesRécapitulatif - Conteneur génériqueEntraînez-vous par vous-même : Compilateur C++ en ligne