Aide-mémoire C++ pour INF1010
1. Classes, constructeurs, allocation dynamique
| Déclaration (.h) | Jamais using namespace std; dans un .h. Définitions dans le .cpp dans le même ordre (sauf génériques : dans le .h). | |
|---|---|---|
| Définition (.cpp) | Liste d'initialisation obligatoire pour const, références, attributs objets sans constructeur par défaut, classe de base. Ordre réel = ordre de déclaration des attributs. | |
| Constructeurs | Par défaut
| Pas de type de retour. Un tableau T t[3] ou new T[3] exige le constructeur par défaut. |
| Ordre de construction / destruction | Construction : classe(s) de base (ordre de la déclaration de classe), attributs (ordre de déclaration), corps. Destruction : corps du destructeur, attributs (inverse), base. Variables locales détruites à l'accolade fermante, ordre inverse de déclaration. Temporaire : fin de l'expression. Paramètre par valeur : fin de la fonction. Objet dynamique : au | À appliquer pour « Donnez l'affichage ». |
| Pile et tas | Un new = un delete, un seul propriétaire. Erreurs : fuite, pointeur pendant, double delete, delete sur un tableau, delete sur une variable locale. | |
| Agrandir un tableau | Ce que vector fait tout seul. |
2. const, passage de paramètres, vector
| Méthode const |
Le const fait partie de la signature : à répéter dans le .cpp. Surcharge possible : | Accesseurs, affichage, calculs, comparaisons : const. | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Paramètres |
Retour : par valeur (toujours sûr) ; Surcharge résolue à la compilation par les types des arguments ; | |||||||||||||||||||||||||||||||
| std::vector | Paramètre : const vector<T>&. push_back peut réallouer (pointeurs vers éléments invalidés). Un vector de pointeurs bruts ne détruit pas les objets. Copie de vector = copie profonde des éléments. | |||||||||||||||||||||||||||||||
3. Composition, agrégation, pointeurs intelligents
| Reconnaître la relation |
Composition : « possède », durée de vie liée, pas de partage. Agrégation : « utilise », indépendant, partageable. Héritage : « est un ». | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| unique_ptr | Un attribut unique_ptr rend la classe non copiable par défaut : écrire le constructeur de copie (make_unique<T>(*autre.ptr_)) ou interdire la copie. | ||||||||||||||||||||||
| shared_ptr | Jamais deux pointeurs intelligents depuis le même pointeur brut ; jamais delete p.get(). weak_ptr : observe sans compter (cycles). | ||||||||||||||||||||||
4. this, opérateurs, copie et affectation
| this |
| |
|---|---|---|
| Signatures des opérateurs | Membre : opérande gauche = objet. Libre/friend : opérande gauche d'un autre type ou commutativité. friend = fonction globale avec accès privé (pas de T::). Sans friend : passer par les accesseurs publics. a + b → a.operator+(b) ou operator+(a, b). Pas de nouveaux opérateurs, priorité inchangée. | |
| Règle des trois | Nécessaire si la classe possède un pointeur brut (new / delete) ou un unique_ptr. Inutile avec string, vector, shared_ptr, types simples (copie membre à membre correcte). Copie superficielle = partage involontaire, pointeur pendant, double delete. | |
| Copie-et-échange (TP2) | unique_ptr dupliqué (copie profonde), shared_ptr copiés (partage). |
5. Héritage et polymorphisme
| Syntaxe | Héritage public = « est un ». Sans appel explicite, le constructeur par défaut de la base est utilisé. Seule la base directe dans la liste. Constructeurs, destructeurs, operator= non hérités. | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Liaison | Non virtuelle : choisie à la compilation d'après le type déclaré du pointeur ou de la référence (liaison statique). Virtuelle : choisie à l'exécution d'après le type réel (liaison dynamique), uniquement via pointeur ou référence. Copie par valeur dans le type de base = découpage (slicing), version de la base. Appel virtuel dans un constructeur/destructeur : version de la classe en cours. | Collection polymorphe : vector<shared_ptr<Base>> ou unique_ptr ; jamais vector<Base>. | ||||||||||||
| Abstraite / interface | Au moins une méthode | Erreur « impossible d'instancier une classe abstraite » : pure non redéfinie ou signature différente. | ||||||||||||
| Accès |
Héritage protected / private : abaisse les niveaux (public devient protected / private). | |||||||||||||
6. Conversions
| Ascendante | Base* p = &derivee; Base& r = derivee; shared_ptr<Base> s = make_shared<Derivee>(); : implicite, toujours valide. Base b = derivee; : valide mais découpe. | |
|---|---|---|
| Descendante | Jamais implicite. Préférer une méthode virtuelle à une chaîne de dynamic_cast. Usage légitime : opération propre à une dérivée (recharger une Batterie). |
7. Héritage multiple et généricité
| Héritage multiple | Cas sain : une classe concrète + des interfaces. | |
|---|---|---|
| Fonction générique | Définition dans le .h. Erreurs à l'instanciation (T sans l'opérateur requis). Appel : filtrerParType<Pince>(liste). | |
| Classe générique | Tout dans le .h. Dans la classe, Liste = Liste<T>. shared_ptr : == compare les adresses. |
8. STL : conteneurs et itérateurs (final)
| Conteneurs |
| ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Itérateurs | Un itérateur = pointeur généralisé : *it, it->, ++it. end() = après le dernier. Catégories : aléatoire (vector, deque), bidirectionnel (list, set, map), avant. | ||||||||||||||||||||||||||||
9. STL : algorithmes, foncteurs, lambdas (final)
| Algorithmes | b, e = v.begin(), v.end(). remove ne change pas la taille : il compacte et retourne la nouvelle fin. list a ses propres sort(), remove(), unique(). | |
|---|---|---|
| Foncteur | Un foncteur passe par valeur : for_each retourne le foncteur, utile pour récupérer son état. | |
| Lambda | Une lambda = foncteur anonyme généré par le compilateur. Type unique : la recevoir dans un paramètre template ou std::function. Capture par valeur figée à la création ; mutable pour la modifier. |
10. Membres statiques, exceptions, Python (final)
| static | Variable de classe partagée par tous les objets ; existe même sans objet. static const int N = 3; initialisable dans la classe. Fonction libre static : visible dans son fichier seulement. Variable locale static : conserve sa valeur entre les appels. | |||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Exceptions | Le reste du bloc try est abandonné ; catch essayés dans l'ordre ; les objets locaux sont détruits (pointeurs intelligents libérés, pointeurs bruts fuient). Non attrapée : std::terminate. Hiérarchie : exception → logic_error (invalid_argument, out_of_range, length_error) et runtime_error (overflow_error, range_error) ; bad_alloc, bad_cast. noexcept : ne lance pas. Un destructeur ne lance jamais. | |||||||||||||||||||||||||||
| Python vs C++ |
Python : pas de types déclarés, pas d'accolades, pas de surcharge de fonctions, polymorphisme par défaut (méthodes « virtuelles »), | |||||||||||||||||||||||||||
Erreurs de compilation fréquentes et leur cause
| Message (clang / MSVC) | Cause probable | Correction |
|---|---|---|
| member function not viable: 'this' argument has type 'const T' | méthode non const appelée sur un objet ou une référence const | ajouter const à la méthode |
| cannot assign to non-static data member within const member function | modification d'un attribut dans une méthode const | retirer const (mutateur) ou ne pas modifier |
| call to deleted constructor of 'unique_ptr' | copie d'un unique_ptr (ou d'une classe qui en contient un) | std::move, ou écrire le constructeur de copie |
| no matching constructor for initialization | constructeur par défaut absent (tableau, vector(n), base non appelée) ou mauvais arguments | appeler la base / fournir le constructeur |
| variable of abstract class type / impossible d'instancier une classe abstraite (C2259) | objet par valeur d'une classe abstraite, ou pure non redéfinie (signature différente) | pointeur ou référence ; vérifier les signatures avec override |
| call to 'f' is ambiguous | surcharges indiscernables (f(T) et f(T&)), ou membre présent dans deux bases | qualifier (A::x), retirer une surcharge |
| undefined reference / symbole externe non résolu (LNK2019) | méthode déclarée mais pas définie ; template défini dans un .cpp ; variable static non définie | définir dans le .cpp (ou le .h pour un template) ; int T::x_ = 0; |
| out-of-line definition does not match any declaration | signature du .cpp différente du .h (const oublié, type de paramètre) | copier la signature exacte |
| -Wreorder : field 'x_' will be initialized after field 'y_' | liste d'initialisation dans un ordre différent de la déclaration | réordonner la liste |
| comparison of integers of different signs (-Wsign-compare) | int i < v.size() | size_t i |
| 'override' : method with override specifier did not override any base class methods | la base n'a pas de méthode virtuelle de cette signature | ajouter virtual dans la base ou corriger la signature |
| cannot convert 'Base*' to 'Derivee*' | downcast implicite | dynamic_cast<Derivee*> |
| you cannot assign to a variable that is const (C3892) | écriture via une référence ou un itérateur const | utiliser une version non const |