Programmation moderne en C++ de C++11 à C++17

Référence : CPP02

Programmation moderne en C++ de C++11 à C++17

Modernisez votre code C++ avec les fonctionnalités introduites par C++11, C++14 et C++17 pour développer des applications plus robustes, performantes et maintenables.

Durée

4 jours
32 heures

Niveau

Intermédiaire

Modalité

Présentiel / Distanciel

Référence

CPP02

Présentation

Cette formation présente les évolutions majeures du C++ moderne à travers les standards C++11, C++14 et C++17. Les participants apprennent à écrire un code plus sûr, plus expressif et plus maintenable en exploitant les nouvelles fonctionnalités du langage.

Public concerné

  • Développeurs C++ souhaitant moderniser leur codebase C++03/98.
  • Développeurs Java, C# ou Python migrant vers C++ avec des bases acquises.

Prérequis

  • Maîtrise des bases du C++ : syntaxe, classes, pointeurs et références.
  • Expérience pratique en C++03.

Objectifs de la formation

  • Comprendre les évolutions des standards C++11, C++14 et C++17.
  • Écrire du code C++ plus sûr, expressif et maintenable.
  • Maîtriser la sémantique de déplacement et l'optimisation des copies.
  • Utiliser les smart pointers et l'idiome RAII.
  • Exploiter les lambdas et std::function.
  • Mettre en œuvre la programmation concurrente avec std::thread.
  • Utiliser efficacement les nouvelles fonctionnalités de la STL.

Programme détaillé

  • Historique et évolution du langage C++.
  • Bref historique du langage.
  • Philosophie du C++ moderne.
  • Outils de développement.
  • Modèle mémoire : rappel sur la pile, le tas et les sections de données.
  • Modèle mémoire d'un programme exécutable.

  • La constante nullptr.
  • auto et decltype.
  • Initialisation uniforme { }.
  • Expressions constexpr.
  • Littéraux modernes : littéraux de caractère et chaînes littérales brutes.
  • Espaces de noms imbriqués (C++17).
  • Espaces de noms inline (C++11).
  • Alias d'espaces de noms.
  • Espaces de nommage anonymes.

Travaux pratiques
  • Refactoring d'un code legacy : remplacement de NULL, boucles for et enum.
  • Création de fonctions constexpr pour des calculs à la compilation.
  • Utilisation de l'initialisation uniforme pour variables et conteneurs.
  • Utilisation des chaînes littérales brutes pour simplifier les chemins de fichiers et expressions régulières.
  • Organisation du code avec espaces de noms imbriqués et alias.

  • Améliorations syntaxiques
  • Range-based for (C++11).
  • Énumérations fortement typées (enum class) (C++11).
  • Structured bindings (C++17).
  • Initialisation dans les instructions if et switch (C++17).
  • Attributs du langage introduits en C++11, C++14 et C++17.

Travaux pratiques
  • Utilisation de range-based for pour parcourir différentes collections.
  • Création d'enum class représentant des états ou des codes d'erreur.
  • Utilisation d'un switch avec initialisation de variable.
  • Utilisation des structured bindings avec std::pair et std::tuple.

  • Catégories d'expressions : lvalue, rvalue et prvalue.
  • Sémantique de déplacement (Move Semantics).
  • Utilisation de std::move.
  • Perfect Forwarding avec std::forward.
  • Règle des 0/3/5.
  • Copy Elision et Return Value Optimization (RVO) (C++17).
  • Les opérateurs de conversion : const_cast, static_cast et reinterpret_cast.

Travaux pratiques
  • Implémentation d'une classe de gestion de ressources avec constructeur de copie, constructeur de déplacement, opérateurs d'affectation de copie et de déplacement.
  • Utilisation de std::move et std::forward dans des fonctions génériques afin de mettre en œuvre le Perfect Forwarding.

  • Initialisation des membres non-statiques (C++11).
  • Constructeurs délégués (C++11).
  • Directives =default et =delete.
  • Héritage et délégation des constructeurs.
  • Contrôle de l'héritage et de la virtualité avec override et final.
  • Contrôle du downcasting avec l'opérateur dynamic_cast.
  • Modèle de classe std::initializer_list.
  • std::string_view : remplacement performant des chaînes.

Travaux pratiques
  • Conception d'une hiérarchie de classes polymorphiques utilisant override et final afin de garantir la bonne implémentation des interfaces.
  • Utilisation de =default et =delete pour contrôler précisément les opérations de copie et de déplacement d'une classe.
  • Optimisation des paramètres de fonctions avec std::string_view.

  • Pointeurs de fonctions.
  • Foncteurs : objets fonctions et opérateurs d'appel.
  • Expressions lambda.
  • Syntaxe complète des expressions lambda.
  • Captures de variables.
  • Closures et durée de vie des captures.
  • Utilisation de auto et decltype avec les lambdas.
  • Lambdas génériques (C++14).
  • std::function et le type-erasure pour les objets appelables.
  • Utilisation de std::function pour stocker et transmettre des callbacks génériques.

Travaux pratiques
  • Implémentation d'un tri personnalisé pour une structure de données complexe avec une lambda générique comme comparateur.
  • Création d'un système de gestion d'événements ou de notifications utilisant std::function.

  • L'idiome RAII : principe fondamental de la gestion automatique des ressources.
  • Les pointeurs intelligents : std::unique_ptr, std::shared_ptr et std::weak_ptr.
  • Fonctions de création : std::make_shared et std::make_unique.
  • Pièges courants liés à l'utilisation des smart pointers.

Travaux pratiques
  • Refactorisation d'un code utilisant new / delete vers une gestion mémoire moderne.
  • Détection et résolution d'un cycle de références avec shared_ptr.

  • Alias de template avec using (C++11).
  • Variadic templates (C++11).
  • Fold expressions (C++17).
  • Types locaux et non nommés comme arguments template.
  • Sélection de branche à la compilation avec if constexpr (C++17).
  • CTAD (Class Template Argument Deduction) (C++17).

Travaux pratiques
  • Implémentation d'une fonction variadique générique.
  • Création d'un template de fonction utilisant if constexpr pour adapter son comportement selon les propriétés du type.
  • Refactorisation de code existant pour exploiter CTAD lors de l'instanciation de templates complexes.

  • Nouveaux conteneurs : std::array, std::forward_list, std::unordered_map, std::unordered_set, std::tuple.
  • Nouveaux algorithmes et utilitaires.
  • Algorithmes de conteneurs : std::all_of, std::any_of, std::none_of, std::iota (C++11).
  • Algorithmes utilitaires : std::clamp, std::gcd, std::lcm (C++17).
  • Types sûrs : std::optional, std::variant, std::any.
  • Manipulation des chemins de fichiers avec std::filesystem.
  • Espace de noms std::chrono.
  • Classes duration et time_point.
  • Horloges : system_clock, steady_clock, high_resolution_clock.
  • Mesure des performances d'algorithmes.
  • Littéraux de durée (C++14) : h, min, s, ms, us, ns.

Travaux pratiques
  • Manipulation de collections de données avec les algorithmes STL modernes.

  • Création et terminaison des threads avec std::thread.
  • Partage de données entre plusieurs threads.
  • Synchronisation des opérations concurrentes.
  • Les types atomiques.

Travaux pratiques
  • Création d'une application multithreadée simple.
  • Accès concurrent à une ressource partagée avec std::mutex et std::lock_guard.
  • Prévention des conditions de course et garantie de la sécurité des données.