Le langage C++
Cette page donne quelques ressources pour le module de Prog2 de l’ENS Rennes. Si vous avez des questions, n’hésitez pas à contacter Martin Quinson, Mathieu Laurent ou Jean-Michel Gorius.
Les prérequis du module sont une bonne compréhension du langage C (module Sys1 du premier semestre), une bonne maîtrise de l’algorithmique (Algo1; Algo2 couvre des choses plus avancées que ce que l’on utilisera dans ce module) et une bonne connaissance des concepts des langages de programmation (module Prog1 au premier semestre). Une première exposition aux objets en Java, Python ou un autre langage est un plus, mais ce n’est pas indispensable.
L’objectif du module est de donner une bonne maîtrise du langage C++. Le temps imparti ne permet pas de couvrir l’intégralité de ce langage si vaste et complexe, mais nous couvrirons les bases du langage (STL, flux, templates, surcharge d’opérateurs), la norme C++11 (RAII, smart pointers) et nous aborderons quelques points de la norme C++23 (ranges). Nous verrons également comment organiser un projet selon les cannons de la programmation orientée objet (polymorphisme, dispatch, covariance, classes et héritage), ainsi que l’implémentation classique de ces concepts en C++ (vtable, name mangling et schémas mémoires). Si le temps le permet, nous aborderons des notions plus avancées de génie logiciel (test, intégration continue).
Polycopié du cours
En vérité, les documents de cours ne sont pas exactement des polycopiés. Il s’agit plutôt de mes notes de cours : c’est ce que j’utilise en séance pour structurer mon discours et ne rien oublier. Je n’utilise pas toutes les sections à l’oral (en fonction du temps disponible), et je change parfois l’ordre des parties en live (en fonction de mon inspiration et des retours de l’assistance).
Cela fait que le texte est concis, car j’ai besoin de pouvoir m’y repérer en live pendant que je parle en cours. S’il y a trop de lettres, je risque de m’y perdre. Il sera donc rapide à relire pour vous aussi, si vous savez de quoi il retourne. En revanche, ce document n’est pas suffisamment rédigé pour être auto-suffisant et vous permettre de tout comprendre sans venir en cours.
Voir aussi les extraits de code distribués chaque semaine ci-dessous.
Semaine 1: Better C
L’objectif de cette semaine est de présenter les améliorations de C++ par rapport au C, en se limitant aux aspects de programmation impérative. On parlera donc de std::string, des flux d’entrée/sortie, des références, de la bibliothèque standard (les conteneurs, les itérateurs et les algorithmes), et des templates de fonction.
- Extraits de code étudiés en cours: Better C.
- Sujet du TP1 flôts et vecteurs (source fourni).
Semaine 2: Introduction à la POO
Cette semaine, on aborde le second paradigme de programmation utilisable en C++ : la programmation orientée objet. Nous parlerons d’encapsulation, de constructeurs, de const et static, de surcharge d’opérateurs et d’objets automatiques, temporaires ou dynamiques. Nous nous attacherons à comprendre comment ce paradigme peut aider à mieux organiser son code, en pratique.
- Extraits de code étudiés en cours: Programmation Orientée Objet.
- Sujet du TP2 Complexes, schémas mémoire et LogOOP (source fourni).
- Document supplémentaire: David Goldberg, What Every Computer Scientist Should Know About Floating-Point Arithmetic. ACM Computing Surveys, Vol 23, No 1, March 1991.
Semaine 3: Conception objets et héritage de classes
On continue avec l’OOP avec une méthodologie permettant de modéliser un problème sous forme de classes collaborant entre elles. Nous parlerons ensuite d’héritage, de liaison dynamique, de compatibilité de classes, d’exceptions et de transtypage.
- Extraits de code étudiés en cours: Héritage.
- Sujet du TP3: Héritage et dipôles (source fourni).
- Document supplémentaire: Kent Beck et Ward Cunningham. A Laboratory for Teaching Object-Oriented Thinking, in Proceedings of OOPSLA’89, 1989.
Semaine 4: Implémentation de l’héritage en C++
Cette semaine, nous nous interressons à l’implémentation du C++, en particulier la représentation des classes et objets en mémoire (memory layout) et la décoration des noms de méthodes (name mangling). C’est important pour comprendre ce qui se passe quand on redéfinit une méthode dans une classe fille (overriding), ce qui se passe quand on surcharge une fonction (overloading), et quelle est cette horreur nommée réécriture de méthode (overwriting).
- Extraits de code étudiés en cours: Implémentation de l’héritage.
-
Sujet du TP4: Héritage et figures récursives (source fourni).
- Lancement du projet DeepDiep, template de projet gitlab.
On peut télécharger le source fourni sans passer par notre gitlab.
Le but de ce projet est de réaliser un jeu de combat entre des petits robots, librement inspiré de diep.io. Il y aura de la programmation orientée objet, un peu d’algorithmique, un peu de graphisme et de manière optionnelle, très peu d’intelligence artificielle (même pas profonde, malgré le titre).
Séance 5: Variance et C++ moderne
Cette semaine, nous pouvons terminer notre revue de l’héritage en C++ avec les notions de covariance, invariance et contravariance. Cela donne de beaux casses-têtes, particulièrement difficile à comprendre sans les notions abordées depuis 3 séances sur l’héritage en C++.
Dans un second temps, nous étudierons les fonctionnalités “modernes” du C++ permettant de ne plus gérer à la main les ressources systèmes comme la mémoire. Ca n’égale peut-être pas le borrow checker de Rust, mais c’est déjà bien plus pratique que de tout faire à la main comme en C.
- Extraits de code étudiés en cours: Better C++.
- Sujet du TP5: Smart dipôles et figures récursives intelligentes (code fourni)
Séance 6: Programmation fonctionnelle en C++
Cette semaine, nous verrons certains élément se programmation fonctionnelles ajoutés au C++ dans les dernières versions du langage. Au programme: lambdas et ordre supérieur, pureté et immutabilité, ranges et views. Nous parlerons aussi un peu de programmation générique et de templates si le temps le permet.
- Extraits de code étudiés en cours: C++ fonctionnel.
- Sujet du TP6: mémoisation et itérateurs en C++ (source fourni).
Séance 7: fin de la programmation fonctionnelle
Cette semaine, nous verrons tout ce que nous n’avons pas eu le temps de voir en fonctionnel la semaine passée. En TP aussi, nous continuons sur le TP 6.
Séance 8: Génie logiciel et patrons de conception
Maintenant que nous avons fini de voir les principaux aspects de ce langage, nous pouvons parler de méthodologie de conception de code. Pour cela, nous aborderons les patrons de conception. Il ne faut pas en faire une religion, mais ces concepts donnent un vocabulaire bien pratique pour parler de l’architecture des programmes.
- Extraits de code étudiés en cours: SOLID et patrons.
- Sujet du TP8: mémoisation et itérateurs en C++ (source fourni).
Séance 9: Génie logiciel et tests
Pour finir ce petit tour des notions importantes du génie logiciel, nous parlerons cette semaine des différents types de tests logiciel, ainsi que de comment et pourquoi en écrire.
- Sujet du TP9: refactorer du code en C et écrire du beau code C++ (source fourni).
Projet final
Le module terminera avec un projet mystère découpé en différentes étapes.
- Étape 2: écrire du beau code C++ (source fourni).
TP supplémentaires
Ces vieux sujets ne sont plus utilisés dans le module, mais ils restent intéressants pour celleux qui souhaitent approfondir leur compréhension des notions vues en cours.
- Le TP Expressions (code fourni) vous permettera de revoir plusieurs sujets importants du module, tout en découvrant un problème classique dans le monde des langages OO.
- Le TP d’entrainement OO (code fourni) regroupe trois exercices assez long tombés en partiel les années précédentes. L’objectif pédagogique est toujours le même : vous permettre de vous entraîner à concevoir un projet orienté objet en découpant de façon intelligente un code fourni en C un peu dégueu.
Quelques ressources utiles
Mon livre préféré pour apprendre le C++ est intitulé Exercices en langage c++, par Claune Delannoy. Il contient beaucoup d’exercices, mais surtout, il contient des petits résumés de cours au début de chaque chapitre. Ce livre est excellent pour apprendre à utiliser le langage C++, même si le cours couvre un peu plus de matériel pour comprendre C++ en profondeur.
On trouve énormément de choses sur internet, et voici une petite sélection de ressources intéressantes portant sur le C++ moderne.
- Course Reader
de Stanford (copie locale). Il s’agit du poly d’un cours de C++ à Stanford, très
bien fait. C’est complet, et le curseur est assez bien placé entre
“guide de référence contenant tout mais indigeste pour commencer” (comme
cppreference) et “tutoriel
compréhensible par tous mais ne couvrant que 2% du langage”.
Les slides associés sont également accessibles. Ils sont plus rapides à lire, puisqu’ils contiennent moins d’information. - Notes de cours de David Kieras (UMichigan). Ce site contient énormément d’informations utiles (presque trop).
- learncpp, un site très complet. Peut-être un peu plus pédagogique que cppreference pour les débutants, mais moins bien rangé.
- InformaticienZero: Un tutoriel en français assez bien fait. Certaines parties manquent (par exemple sur les smart pointer), mais c’est un très bon début.
- On trouve aussi plusieurs blogs plutôt bien faits sur le C++, souvent centrés sur les nouveautés de C++23 et la suite.
Examens des années passées
- 2020-2021
- 2021-2022 (correction indicative)
- 2022-2023 (correction indicative)
- 2023-2024 (correction indicative)
- 2024-2025 (correction indicative, code à refactorer, ma version refactorée)
Autres cours
Ce module fait partie d’un ensemble relativement cohérent d’enseignements à l’ENS Rennes:
- SYS1: Programmation C, réseau et introduction aux systèmes informatiques (L3S1).
- GL: Programmation C++ et génie logiciel (L3S2).
- ProgSys: Programmation système: forks, I/O, synchronisations et threads.
- HPC: Programmation haute performance: pratique de MPI (M1S1).
Merci de signaler toute erreur sur
framagit (vous devez
être authentifié sur framagit pour cela).
Les collègues
enseignants peuvent demander un accès “Guest” au projet (directement
sur l’interface gitlab), pour accéder aux sources et corrigés (qui
sont masqués surtout pour cacher les examens avant le jour J).