Menu
Coddy logo textTech

Smart Pointers en C++

Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy — leçon 15 sur 104.

Les pointeurs intelligents (smart pointers) sont des classes wrappers 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 la 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 nullptr

shared_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 2

weak_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.

challenge icon

Défi

Facile

Construisons un système de partage de documents qui démontre les différents modèles de propriété des pointeurs intelligents (smart pointers). Vous verrez 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.

Vous allez créer deux fichiers pour organiser votre code :

  • Document.h : Définissez une classe Document qui 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 retourne le titre
  • main.cpp : Démontrez les trois types de pointeurs intelligents en lisant un titre de document depuis l'entrée, puis :
    • Créez un unique_ptr vers un Document avec le titre saisi
    • Affichez "Unique owner: <title>"
    • Transférez la propriété à un autre unique_ptr en utilisant std::move
    • Affichez "Ownership transferred"
    • Créez un shared_ptr vers un nouveau Document avec le titre "SharedDoc"
    • Créez un second shared_ptr pointant vers le même document
    • Affichez "Shared owners: <count>" en utilisant use_count()
    • Créez un weak_ptr à partir de l'un des pointeurs partagés
    • Utilisez lock() pour accéder au document via le pointeur faible et affichez "Weak access: <title>"

N'oubliez pas d'inclure <memory> pour les pointeurs intelligents. Utilisez std::make_unique et std::make_shared pour créer vos pointeurs intelligents. Les messages du destructeur vous aideront à voir quand chaque document est automatiquement nettoyé à la fin du programme.

Incluez votre fichier d'en-tête dans main.cpp en utilisant #include "Document.h".

Aide-mémoire

Les pointeurs intelligents sont des classes d'enveloppement qui gèrent automatiquement la mémoire du tas. Incluez l'en-tête <memory> pour les utiliser.

unique_ptr

Propriété exclusive - un seul pointeur peut posséder la ressource à la fois :

std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack();  // Use like a regular pointer

// Transfer ownership with std::move
std::unique_ptr<Player> player2 = std::move(player);
// player is now nullptr

shared_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;  // Both own the resource

std::cout << p1.use_count();  // Prints 2

weak_ptr

Observateur sans propriété d'un shared_ptr. Utile pour briser 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()) {  // Convert to shared_ptr
    locked->attack();
}

Bonnes pratiques : 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 au mot-clé new brut.

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;
}
quiz iconTestez-vous

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