C++ Academy · Leçon

Gardes de portée

Effectuer le nettoyage à la sortie d’une portée

Leçon 4 sur 413 étapes

Gardes de portée est une leçon C++ Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C++ Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C++ Academy comprend 4 leçons au total.

Qu’est-ce qu’une garde de portée ?

Une garde de portée est un objet RAII dont le seul rôle est d’exécuter une action de nettoyage lorsqu’il sort de sa portée — même en cas de retour anticipé ou d’exception.

Le problème résolu

Sans garde, il est facile d’oublier le nettoyage après un return anticipé ou un throw. Une garde de portée rend cette action automatique.

Garde-verrou : une garde de portée standard

std::lock_guard verrouille un mutex lors de sa construction et le déverrouille lors de sa destruction — une garde de portée intégrée pour les verrous.

#include <mutex>

std::mutex m;

void critical() {
    std::lock_guard<std::mutex> lk(m);   // locked
    // ... work ...
}                                        // unlocked automatically

Une garde écrite à la main

Vous pouvez écrire une garde qui contient une fonction et l’appelle dans le destructeur.

#include <iostream>
#include <functional>

class ScopeGuard {
    std::function<void()> fn;
public:
    ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
    ~ScopeGuard() { fn(); }
};

int main() {
    ScopeGuard g([] { std::cout << "cleanup\n"; });
    std::cout << "work\n";
}

Le nettoyage s’exécute lors d’un retour anticipé

Comme le destructeur s’exécute à la sortie de portée, l’action de la garde s’exécute quel que soit le chemin par lequel la fonction se termine.

#include <iostream>
#include <functional>

class ScopeGuard {
    std::function<void()> fn;
public:
    ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
    ~ScopeGuard() { fn(); }
};

void run(bool stop) {
    ScopeGuard g([] { std::cout << "always cleaned\n"; });
    if (stop) return;
}

int main() { run(true); }

Le nettoyage s’exécute en cas d’exception

Si une exception se propage à travers la portée, le destructeur de la garde s’exécute tout de même et libère la ressource en toute sécurité.

Annuler une garde

Vous pouvez parfois vouloir ignorer le nettoyage, lorsque l’opération a réussi. Les véritables gardes proposent une méthode dismiss() pour désactiver l’action.

#include <iostream>
#include <functional>

class ScopeGuard {
    std::function<void()> fn;
    bool active = true;
public:
    ScopeGuard(std::function<void()> f) : fn(std::move(f)) {}
    void dismiss() { active = false; }
    ~ScopeGuard() { if (active) fn(); }
};

int main() {
    ScopeGuard g([] { std::cout << "rollback\n"; });
    g.dismiss();   // success: no rollback
}

Utiliser pour annuler une opération

Les gardes de portée sont particulièrement utiles dans le code transactionnel : enregistrez une action d’annulation, effectuez le travail, puis désactivez la garde en cas de réussite.

Les gardes sont uniquement déplaçables

Une garde ne devrait pas être copiée : la copie exécuterait l’action deux fois. Rendez les gardes uniquement déplaçables ou non copiables.

Utilitaires standard et de bibliothèque

std::scoped_lock protège plusieurs mutex, et des bibliothèques comme GSL fournissent finally. De nombreuses bases de code proposent un petit utilitaire ScopeGuard.

Préférer les types RAII spécifiques

Lorsqu’un type RAII dédié existe (garde-verrou, pointeur unique, flux de fichier), préférez-le. Utilisez une garde de portée générique uniquement pour un nettoyage ponctuel sans enveloppe naturelle.

Vérification rapide

Vérifiez votre compréhension des gardes de portée.

Récapitulatif

Vous avez appris qu’une garde de portée exécute automatiquement le nettoyage à la sortie de portée grâce à RAII. Elle gère les retours anticipés et les exceptions, prend en charge l’annulation avec dismiss() et devrait être uniquement déplaçable. Préférez les types RAII dédiés lorsqu’ils existent.

Gratuit pour commencer

Apprends C++ avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
51
Leçons
203

Questions Fréquemment Posées

La leçon « Gardes de portée » est-elle gratuite ?

Oui — le texte complet de « Gardes de portée » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C++ Academy, passe à CoddyKit PRO. Le cours C++ Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Gardes de portée » ?

Effectuer le nettoyage à la sortie d’une portée Tu pratiques C++ Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer C++ Academy ?

Aucune expérience préalable n'est requise. C++ Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Gardes de portée » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon C++ Academy ?

Oui. Chaque leçon C++ Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Le principe RAII
  2. Destructeurs et nettoyage
  3. Règle des trois et des cinq
  4. Gardes de portée
← Retour à C++ Academy