Logo HE-ARC Logo HES-SO

1242.2 Langage C++ - 2025-2026

Chapitre 2

Des classes et des objets

1. Introduction

2. Définition d'une classe

3. Implémentation d'une méthode

4. Instancier des objets

5. Les constructeurs

6. Le destructeur

7. Membres constants

8. this, Membres statiques, friend

9. Diagrammes UML

10. =delete et =default

2.1 Paradigmes de programmation

Procédurale / impérative

Séparation des données et des fonctions

Une fonction agit sur des données


Orientée objet (POO)

Regroupement des fonctions et données dans un objet

Envoi de "messages" entre objets

2.1 Principe de la POO

Décrire les objets et les actions possibles sur ces objets


Avantages

Approche naturelle

Code réutilisable

Modulaire

Plus facile à maintenir / à faire évoluer

Meilleure gestion pour les gros projets

2.1 Notion de classe

C



                        int balance = 0;
          
                        void deposit(int x)
                        {
                          balance += x;
                        }
          
                        int main(void)
                        {
                          deposit(15);
          
                          return 0;
                        }

C++


          
                        class Account
                        {
                          int balance{0};
          
                          void deposit(int x)
                          {
                            balance += x;
                          }
                        };
          
                        int main()
                        {
                          Account myAccount;
                          Account otherAccount;
          
                          myAccount.deposit(15);
          
                          return 0;
                        }

2.1 Classe vs Objet

Une classe est un type défini par le programmeur

Classe

Un objet est une instance de cette classe

Objet

2.1 Principes de POO

Une classe est la description abstraite d'un objet. Elle regroupe des attributs et des méthodes


Attributs

Appelés aussi des variables membres (de la classe)

Décrivent l'état de l'objet

Exemples : vitesse, poids, nombre de passagers, etc.


Méthodes

Appelées aussi des fonctions membres (de la classe)

Décrivent les actions qu'un objet peut effectuer

Exemples : démarrer, accélérer, freiner, etc.

2.1 Exemple de classe

Définition de la classe Point


                        
                        #include <print>
                        
                        // Class name: Point
                        class Point
                        {
                          public:

                            // Methods
                            void init(int, int);
                            void translate(int, int);
                            void print()
                            {
                              std::println("({},{})", x, y);
                            }
                            
                            // Attributes
                            int x{0};
                            int y{0};
                          };
                        
                        

2.1 Exemple de classe

Définition des méthodes de la classe Point


                        
                        ...
                        
                        void Point::init(int _x, int _y)
                        {
                          x=_x;
                          y=_y;
                        }
                        
                        void Point::translate(int delta_x, int delta_y)
                        {
                          x += delta_x;
                          y += delta_y;
                        }
                        
                        ...

                      
                      
                      

2.1 Exemple de classe

Utilisation des objets de la classe Point


                        
                        int main()
                        {
                          // Point is a class
                          // p1 is an object of the class Point
                          Point p1;
                          
                          p1.init(-1,2);
                          
                          p1.print();
                          p1.translate(10,10);
                          p1.print();
                          
                          return 0;
                        }
                      
                      

2.1 Caractéristiques d'un objet

Un objet possède un état interne

C'est l'ensemble des valeurs qui décrit l'état de l'objet à un instant donné. Cet état n'est pas directement accessible : l'utilisateur doit y accéder au travers de son interface.

Un objet possède une implémentation

C'est la façon dont l'objet est réalisé. L'implémentation n'est pas accessible à l'utilisateur. 2 classes ayant la même interface peuvent avoir une implémentation différente.

Un objet appartient à une classe

La classe est le "moule" à partir duquel on crée un objet. Un objet en est une instanciation.

Un objet est identifiable (nommable)

On peut distinguer les objets entre eux en les nommant, même s'ils sont de la même classe.

2.2 Déclaration d'une classe en C++

Syntaxe


                        
                        class NomDeLaClasse
                        {
                          public:
                            int uneFonctionMembre();
                            double unAttribut;

                          private:
                            char unAutreAttribut;
                        }; // ⚠️ Do not forget the semicolon
                        
                        

2.2 Déclaration d'une classe en C++

Contrôle d'accès aux membres

public : les membres sont accessibles par tous

private : les membres sont accessibles uniquement par les méthodes de la classe. C'est le mode par défaut.


                
                class XYZ
                {
                  public:
                    void fctPub(){..}
                    int varPub;

                  private:
                    void fctPriv(){..}
                    int varPriv;
                };                
                
                

                
                int main()
                {
                  XYZ x;
                
                  x.fctPub(); // ✅
                  x.varPub=3; // ✅

                  x.fctPriv(); // ⛔
                  x.varPriv=6; // ⛔
                }
                                
                

2.2 Déclaration d'une classe en C++

Contrôle d'accès aux membres

public : les membres sont accessibles par tous

private : les membres sont accessibles uniquement par les méthodes de la classe. C'est le mode par défaut.


                
                class XYZ
                {
                  public:
                    void fctPub(){..}
                    int varPub;

                  private:
                    void fctPriv(){..}
                    int varPriv;
                };                
                
                
                

                void XYZ::fctPub()
                { 
                  varPub = 3;  // ✅
                  varPriv = 6; // ✅
                }
                void XYZ::fctPriv()
                { 
                  varPub = 3;  // ✅
                  varPriv = 6; // ✅
                }                
                                                
                

2.2 Encapsulation

L'implémentation et le type des données sont cachés (peuvent évoluer)

⇒ Permet l'évolutivité des programmes


La visibilité des membres est gérée avec public, private et protected

L'accès aux membres est géré par des accesseurs (getX()) et des modificateurs (setX())

⇒ Garantit la cohérence/sécurité des données

2.2 Encapsulation

Les fonctions sont public, et les données sont private (ou protected)


                
                class Account
                {
                  public:
                    void deposit(int x)
                    {
                      balance += x;
                    }
                    void withdraw(int x)
                    {
                      balance -= x;
                    }
                    int getBalance()
                    {
                      return balance;
                    }

                  private:
                    int balance{0};
                };                
                
                

                int main()
                {
                  Account myAccount;
                  myAccount.deposit(100);
                  myAccount.withdraw(50);
                  auto balance = myAccount.getBalance();
                  std::println("Balance: {}", balance);

                  myAccount.balance = 1000; // ⛔
                  std::println("Balance: {}", myAccount.balance); // ⛔

                  return 0;
                }
                                                
                

2.2 Portée des attributs et des méthodes

Certaines méthodes doivent être publiques

les constructeurs (en général)

les accesseurs, les modificateurs


On recommande de

déclarer les attributs privés

les rendre accessibles par des méthodes publiques (accesseurs et modificateurs).

📌 Note : un membre déclaré sans modificateur d'accès sera private par défaut (accessible uniquement depuis les méthodes de la classe)

2.3 Définition des méthodes

En-ligne

Dans la déclaration de la classe

Mot-clef inline (implicite)

Pour des fonctions courtes


Séparée

Prototype dans déclaration de la classe

Définition hors de la déclaration de la classe

Opérateur de portée ::

2.3 Définition des méthodes

En-ligne


                        
                        class Point 
                        {
                          public:
                            int getX()
                            {
                              return x;
                            }
                            inline void setX(int _x) // 📌 inline is optional here
                            {
                              x = _x;
                            }

                          private:
                            int x{0}, y{0};
                        };
                        
                        

2.3 Définition des méthodes

Séparée


                        
                        // Class declaration
                        class Point
                        {
                          public:
                            void display();

                          private:
                            int x{0}, y{0};
                        };
                        
                        // Point::display() definition
                        inline void Point::display() // 📌 inline mandatory
                        {
                          std::println("({},{})", x, y);
                        }
                                                
                        

2.3 Définitions de méthodes

Organisation d'un projet C++

2 fichiers par classe : classe.h (déclarations classe et membres) + classe.cpp (définitions méthodes)

Directives de non-inclusion multiple dans les interfaces



                // Classe.h
                #ifndef CLASSE_H
                #define CLASSE_H
                ...
                #endif
              


                // Classe.cpp
                #include "classe.h"
              


                // Classe.h
                #pragma once
                ...
              


  
                // Classe.cpp
                #include "classe.h"
              

📌 1 fichier peut contenir plusieurs classes

✅ 1 seule classe par paire de fichiers .h et .cpp

2.3 Définitions de méthodes



                // Point.h
                #pragma once

                class Point
                {
                  public:
                    ...

                    int getX(){return x;} // inline
                    void print();
                };
              


                // Point.cpp
                #include "Point.h"
                ...

                void Point::print()
                {
                  std::println("Point: ({},{})", x, y);
                }                
              


                // main.cpp
                #include "Point.h"

                int main()
                {
                  Point ptA;

                  ...

                  return 0;
                }
              

2.4 Instancier des objets

Instancier : créer un objet à partir d'une classe

Chaque objet dispose de son propre jeu d'attributs

La syntaxe est la même que pour déclarer des variables

Instanciation automatique



                int main()
                {
                  // Allocated on the stack
                  Point p1;
                  ...
                  p1.print();
                  ...
                }
              

Instanciation dynamique



                int main()
                {
                  // Allocated on the heap
                  auto *p = new Point; 
                  ...
                  p->print();
                  ...
                  delete p;
                  p = nullptr;
                }
              

2.4 Remarques

Un type est utilisé pour déclarer des variables

Une classe est utilisée pour instancier des objets


Les attributs et les méthodes sont relatifs à un objet : il est nécessaire de commencer par instancier un objet à partir d'une classe avant de pouvoir accéder à ses membres. C'est pour cette raison que les membres d'une classe sont parfois appelés attributs d'instance ou méthodes d'instance.


2.5 Principe du constructeur

Problème

Entre le moment où un objet est instancié et son initialisation, l'état interne est indéterminé


            
            Point p; // ⚠️ p state is unknown

            p.print(); // ⚠️ (?, ?)

            p.init(3,5);  // Initialisation

            p.print(); // ✅ (3,5)
          

But du constructeur

Initialiser un objet lors de son instanciation

2.5 Principe du constructeur

Instanciation PUIS initialisation


            Point p;
            p.init(3,5);
          

Instanciation ET initialisation

On peut initialiser l'état interne d'un objet lors de son instanciation grâce à un constructeur (méthode spéciale)


            Point p(3,5);
          

Quand on instancie un objet :

1) La mémoire nécessaire est allouée

2) Le constructeur de la classe est automatiquement appelé pour initialiser les attributs

2.5 Définition d'un constructeur

Un constructeur est une méthode avec les caractéristiques suivantes:

Son nom est celui de la classe

Il ne contient pas d'instruction return

Il ne possède pas de type de retour (même pas void)


            class Point
            {
              public:
                Point()
                {
                  x = 0;
                  y = 0;
                }

                private:
                  int x, y;
            };
          

2.5 Définition d'un constructeur

1) ✅ Quand c'est possible, on initialise directement les attributs de l'objet

2) Ce constructeur devient alors le même que le constructeur par défaut


            class Point
            {
              public:
                Point()=default; // 📌 Optional, but clearer

                private:
                  int x{0}, y{0};
            };
          

2.5 Les différents constructeurs

Un constructeur peut avoir des paramètres et peut être surchargé. Il peut être appelé le constructeur :

Par défaut

Point() - Pas de paramètre

«Standard»

Point(T value1, T value2,...) - Plusieurs paramètres

Par recopie

Point(const Point &point) - Un paramètre qui est une référence sur un objet de la classe

De conversion

Point(T value) - Un seul paramètre de type différent de la classe (ci-dessus)

2.5 Constructeurs par défaut

2 façons de définir un constructeur par défaut (sans paramètres)


                
                class Point
                {
                  public:
                    Point()
                    {
                      x = 0;
                      y = 0;
                    }
                    ...
                };
              

                
                class Point
                {
                 public:
                  Point(int a=0, int b=0);
                  ...
                };                 
                
                Point::Point(int a, int b)
                {
                  x=a; y=b;
                }              
                

2.5 Constructeurs par défaut - Remarques

Le constructeur par défaut est appelé chaque fois qu'un objet doit être créé sans arguments

Le compilateur fournit un constructeur par défaut, si le programmeur n'a écrit aucun autre constructeur

Le constructeur par défaut proposé par le compilateur ne fait rien: { } (pour l'instant...)


            
            auto x = Point();
            Point y;

            // ⚠️ Ne jamais mettre de parenthèses !
            //    Sinon, c'est une déclaration de fonction appelée z
            // Point z();

            Point t[10]; // 10 appels de Point()
            auto p = new Point;   // équiv.à: p = new Point()
            auto q = new Point[10]; // 10 appels de Point()
          

2.5 Constructeurs standard

Un constructeur standard est un constructeur qui prend des paramètres


                
                class Point
                {
                 public:
                  Point(int a, int b);
                 ...
                };
                
                
                Point::Point(int a, int b)
                {
                  x=a; y=b;
                }
              

                
                class Point
                {
                 public:
                 // ⚠️ constructeur par défaut !
                  Point(int a=0, int b=0);
                 ...
                };                 
                
                Point::Point(int a, int b)
                {
                  x=a; y=b;
                }
              

2.5 Constructeurs standard - Remarques

Un constructeur standard est appelé lorsqu'un objet doit être créé avec des arguments


            
            Point p1(1, 2);
            auto p2 = Point(1, 2);  
            // ⚠️ Use default CTor
            Point p3[10];
            // ⚠️ Use Point(int, int), then use default CTor
            Point p4[4] = {Point(5, 3)};

            auto p5 = new Point(6, 3);
            delete p5;
            
            auto p6 = new Point[10]; 
            for (int i = 0; i < 10; i++)
            {
              p6[i] = Point(2,3);
            }
            delete[] p6;

            std::vector<Point> v(10, Point(2,3));

2.5 Constructeur standard - this

Le pointeur this contient l'adresse de l'objet courant


          
          Point::Point(int x, int y)
          {
            this->x = x;
            this->y = y;
          }
        

1) Éviter le masquage de l'attribut par un paramètre

2) Améliorer la lisibilité du code source: on distingue mieux les méthodes/attributs de l'objet courant et les fonctions globales

3) Comparer l'adresse de l'objet courant avec celle d'un autre objet.

2.5 Les constructeurs de conversion

Un seul argument obligatoire, d'un autre type simple


          
          class Point 
          {
           public:
            // Conversion constructor from int
            Point(int a) {x = y = a;}
            ...
          };          
        

Exemples


          
          auto p1 = Point(2); 
          Point p2(3); 
          Point p3 = 4; // ⚠️ Implicit conversion          
          p3 = 5; // ⚠️ Implicit conversion
        

📝 2.5 Les constructeurs de conversion

Forcer toutes les conversions à être explicites : explicit


          
          class Point 
          {
           public:
            // Conversion constructor from int
            explicit Point(int a) {x = y = a;}
            ...
          };          
        

Exemples


          
          auto p1 = Point(2); // ✅ Explicit conversion
          Point p2(3); // ✅ Explicit conversion 
          Point p3 = 4; // ⛔ Implicit conversion          
          p3 = 5; // ⛔ Implicit conversion
        

2.5 Constructeurs par copie

Un constructeur par copie est un constructeur qui prend en paramètre une référence constante sur un objet de la classe


          
          class Point 
          {
           public:
            Point(const Point &p) {x = p.x; y = p.y;}
            ...
          };
        

Exemples


          
          Point p1(2,3);
          Point p2(p1); // Copy constructor
          auto p3 = p1; // Copy constructor
        

2.5 Constructeurs par copie

Ce constructeur est souvent appelé implicitement

1) À l'initialisation d'un objet, avec l'opérateur =

Point p2 = anotherPoint;

2) Lorsqu'on passe un objet en paramètre par valeur à une fonction

Add(anotherPoint)

3) Parfois lorsqu'on retourne un objet par valeur (voir copy elision)

return anotherPoint;



📚 Copy elision (cppreference)

2.5 Constructeurs par copie

Le compilateur propose automatiquement un constructeur par copie trivial (bit à bit). On parle de "copie en surface".

⚠️ La copie en surface ne fonctionne pas si l'objet contient des pointeurs ou des références.

Il est souvent nécessaire de redéfinir un constructeur par copie pour réaliser une "copie en profondeur".

2.5 Constructeurs par copie

Problème : 1 ou plusieurs des attributs sont des pointeurs (ou similaires)



          class Point
          {
          public:
            ...
            Point(const Point& point) = default;
            // 📌 Equivalent to:
            // Point(const Point &point)
            // {
            // 	 this->x = point.x;
            // 	 this->y = point.y;
            // 	 this->name = point.name;
            // }         
            ...                    
            void setName(const char *name)
            {
              strcpy(this->name, name);
            }
          
          private:
            ...          
            char *name = nullptr;
          };
        

2.5 Constructeurs par copie

Problème : 1 ou plusieurs des attributs sont des pointeurs (ou similaires)



          int main()
          {
            auto p1 = Point(1, 2, "P1");

            // ⚠️ Shallow copy
            auto p2 = p1;

            // ⚠️ p1 is modified too
            p2.setName("P2");
            
            return 0;
          }          
        

2.5 Constructeurs par copie

Solution : copie en profondeur



          class Point
          {
          public:
            ...
            Point(int x, int y, const char *name = "")
            {
              this->x = x;
              this->y = y;
              this->name = new char[strlen(name) + 1];
              strcpy(this->name, name);
            }
            // ✅ Deep copy: allocate new memory, copy content
            Point(const Point &other) : x(other.x), y(other.y)
            {
              this->name = new char[strlen(other.name) + 1];
              strcpy(this->name, other.name);
            }

          private:
            ...
            char *name = nullptr;
          };
        

2.5 Appels de constructeurs - Exemples



          auto a = Point(1, 1);
          Point b(2, 2);
          Point c = 3; // ⛔ Implicit conversion
          auto d = new Point(4, 4);
          Point e;
          Point f[4];

Initialisation d'objets temporaires, anonymes



          std::println("Distance: {}", distance(Point(10,0), Point(3, 4)));

2.5 Appels de constructeurs - Exemples

2 interprétations différentes pour le = :



          // A)
          auto p = Point(1, 2);

          // B)
          Point p;
          p = Point(1, 2);
        

A) 1 appel au constructeur standard

Cette expression crée l'objet p et l'initialise en rangeant dans p.x et p.y les valeurs 1 et 2

2.5 Appels de constructeurs - Exemples

2 interprétations différentes pour le = :



          // A)
          auto p = Point(1, 2);

          // B)
          Point p;
          p = Point(1, 2);
        

B) 2 appels de constructeurs + 1 affectation

- crée un objet p (constructeur par défaut)

- crée un point anonyme de coordonnées (1,2)

- affecte les valeurs des attributs du point anonyme aux attributs de p

⚠️ Risque si l'opérateur = n'est pas surchargé pour une copie en profondeur !

2.5 Liste d'initialisation



          class Point
          {
          public:
            Point(int a, int b) : x(a), y(b) {}
            ...
          };
        

Une liste d'initialisation est indispensable pour :

1) initialiser un membre constant

2) initialiser un membre de type référence

3) initialiser un membre d'un type sans constructeur par défaut


Valable pour tous les constructeurs

✅ À utiliser autant que possible

2.5 Remarques / Rappels

⚠️ Le constructeur par défaut fourni par le compilateur n'est plus disponible si le programmeur a défini un constructeur

Si un constructeur a des valeurs par défaut pour ses paramètres, celles-ci doivent figurer dans la déclaration de la classe (fichier d'interface : classe.h)

⚠️ Il faut redéfinir le constructeur par copie quand une copie en profondeur est nécessaire

La déclaration d'un tableau d'objets génère autant d'appels au constructeur par défaut que d'éléments dans le tableau

2.6 Le destructeur

Appel implicite à la destruction d'un objet (auto et dynamique)

Syntaxe : comme pour le constructeur par défaut, mais avec ~ devant :



          class Point
          {
          public:
            ...
            ~Point() {...}
            ...
          };
        

1 seul destructeur

Destructeur par défaut généré par le compilateur (trivial)

Permet au programmeur de détruire proprement un objet (libérer la mémoire, fermer les flux, stopper les threads, etc.)

2.6 Le destructeur



              class PointN 
              {
                public:
                  ~PointN();
              };
              
              PointN::~PointN()
              {
                delete [] nom;
              }
            


              int main()
              {
                auto *p = new PointN;
                ...
                delete p;
                ...
                auto *q = new PointN[10];
                ...
                delete [] q;
              }
            

Le destructeur est appelé automatiquement lors de la destruction d'un objet puis la mémoire réservée pour l'objet est libérée (désallouée)


📚 Destructors (cppreference)

2.7 Membres constants

Attributs constants

Un attribut d'une classe peut être qualifié const

Initialisé lors de la construction d'un objet

Ne peut plus être modifié ensuite


          class Segment
          {
            public:
              Segment(int x,int y, int num);
              ...
            private:
              const int ID{0}; // 1) ✅ OK
          };
          
          Segment::Segment(..., int num){..., ID = num;} // ⛔ Error
          ...          
          Segment::Segment(..., int num) : ID(num){...} // ou 2) ✅ OK
        

2.7 Membres constants

Méthodes constantes

Le mot-clé const en fin d'en-tête d'une méthode indique qu'elle ne change pas l'état de l'objet

C'est une méthode de consultation de l'objet


          
          class Point
          {
            // Can modify the object
            void setXY(float newX, float newY);

            // Cannot modify the object
            float getX( ) const;
          };
        

2.7 Membres constants

Méthodes constantes avec objet constant


          const Point pt = ...;

          auto x = pt.getX();
        

pt est constant donc il ne doit pas être modifié par getX()

⇒ la qualification const de getX() est indispensable


✅ Bonne pratique : qualifier const toute méthode qui peut l'être : cela élargit son champ d'application

2.7 Membres constants

Méthodes constantes : surcharge

Le mot-clef const change la signature d'une méthode

⇒ On peut surcharger une méthode non-constante par une méthode constante

La fonction non constante sera appelée par les objets variables, la fonction const sur les objets constants

🌶️ 2.7 Membres constants

Méthodes constantes : surcharge


        
        class Point
        {
          int x,y;
          
          public:
            int X() const {return x;}
            int &X() {return x;}
        };
        


              const Point pC(2, 3);
              int r;
              ...
              r = pC.X(); // ✅ OK
              pC.X() = 15; // ⛔ Error: rvalue
            


              Point p(4,5);
              int r;
              ...
              r = p.X(); // ✅ OK
              p.X() = 15; // ✅ OK: lvalue
            

🌶️ 2.7 Membres constants

Méthodes constantes : surcharge


            
            class Point
            {
              int x,y;
              
              public:
              int &X() const {return x;} // ⛔ Error
            };
          

Comme X() retourne une référence (=> possibilité d'être une lvalue), le compilateur ne peut pas garantir que la méthode soit constante

2.8 Pointeur this

Le pointeur this contient l'adresse de l'objet courant


📌 Les méthodes sont toujours appelées depuis un objet

⇒ L'adresse de l'objet est implicitement passée à la méthode appelée


this est donc le pointeur sur l'objet qui a servi à appeler la méthode

⚠️ this est un pointeur constant


Le déréférencement de this donne l'objet courant !

return *this; retourne l'objet lui-même

Point temp(*this); crée une copie de l'objet courant (constructeur par copie)

2.8 Pointeur this

1) Éviter le masquage de l'attribut par un paramètre :


            
            Point::Point(int x, int y)
            {
              this->x = x;
              this->y = y;
            }
          

2) Améliorer la lisibilité du code source : on distingue mieux les membres de l'objet courant des paramètres


3) Comparer l'adresse de l'objet courant avec celle d'un autre objet

2.8 Membres statiques

2 catégories de membres (attributs et méthodes)

A) Membres d'instance (cas connu)

- Chaque objet d'une classe a ses propres attributs

- Les méthodes sont appelées à partir des objets d'une classe


B) Membres de classe

- Un attribut de classe est unique pour tous les objets d'une classe

- Une méthode de classe peut être appelée à partir de la classe

2.8 Membres statiques


            
            class Point
            {
              public:
                ...
                static int getNbPoints() {return nbPoints;}

              private:
                int x{0}, y{0}; // Unique to each object
                static int nbPoints; // Shared by all objects              
            };
          

⚠️ Un attribut de classe (static) doit être initialisé en dehors de la classe


            
            int Point::nbPoints = 0;

            int main()
            {
              ...
              std::println("Nombre de points: {}", Point::getNbPoints());
            }
          

2.8 Membres statiques - Remarques

⚠️ Une méthode statique ne peut accéder qu'aux membres statiques


            
            class Point
            {
              public:
                ...
                static int GetX() {return x;} // ⛔ Error
            };
          

⚠️ Une méthode statique ne dispose pas du pointeur this


📌 Les méthodes statiques sont utilisables sans instancier un objet

2.8 Classes et fonctions friend

Il est possible de passer outre la protection d'accès aux membres privés d'une classe grâce au mot-clé friend


1) Une fonction amie (friend) d'une classe est une fonction qui, sans être membre de cette classe, a le droit d'accéder à tous ses membres, aussi bien publics que privés


2) Une classe amie (friend) d'une classe C est une classe qui a le droit d'accéder à tous les membres de C

2.8 Classes et fonctions friend

1) Une fonction amie doit être déclarée dans la classe qui accorde le droit d'accès


            
            class Point 
            {
              ...              
              public:
                friend void fctExt(Point &p);
              ...
            };
            void fctExt(Point &p)
            { 
              p.x = 0; // ✅ OK: fctExt is a friend of Point
            }          

            
            int main()
            {
              Point p;
              p.x = 0; // ⛔ Error: x is private
              fctExt(p); // ✅ OK: fctExt is a friend of Point
            }
          

2.8 Classes et fonctions friend

2) Une classe amie doit être déclarée dans la classe hôte


                
                class Host
                {
                  friend class ZeFriend;
                  int x;                  
                  public:
                    Host(int a):x(a){}
                };
            

                
                class ZeFriend
                {
                  public: 
                    void displayHost()
                    {
                      Host h(16);
                      // ✅ OK: ZeFriend is a friend of Host
                      std::println("Host x = {}", h.x);
                    }
                };
              

2.9 Diagrammes UML

Voir cours 2243.2 Génie Logiciel

2.10 =delete et =default

Point()=default force le compilateur à générer un constructeur par défaut

Point()=delete empêche le compilateur de générer un constructeur par défaut


📌 Fonctionne aussi pour le constructeur par copie, et le destructeur


                
                class A
                { 
                  public:
                    A()=default;
                    A(const A&) = delete; // No copy allowed
                    ~A()=default;
                };
              

2.10 Constructeurs délégués

Un constructeur peut appeler un autre constructeur avec des paramètres différents


                
                class A
                {
                  public:
                    A()=default;
                    A(char x, int y) {}
                    A(int y) : A('a', y) {}
                };