Programmer en C++
Les classes : Création d'objets dynamiques

Retour au sommaire

1. Introduction

Jusqu'à présent nous n'avons travaillé qu'avec des objets automatiques. Par exemple :

Point monPoint (10, 3);

monPoint est un objet automatique créé à partir de la classe Point (celle que nous avons définie au début des chapitres sur les classes). Si nous écrivons ce code dans la fonction main(), cet objet sera détruit automatiquement à la fin du programme.
Et alors c'est parfait non ?
Pour ce cas en effet, mais si nous écrivons maintenant notre code dans une fonction utilisée dans notre programme, alors cet objet sera également détruit, non pas en quittant le programme, mais en quittant la fonction.
Ah oui ça peut être génant si nous voulons continuer d'utiliser cet objet dans le programme.
Heureusement nous avons la solution avec la création d'un objet dynamique.

2. Création d'un objet dynamique

Point * ptrPoint;     // Creation d'un pointeur de type Point
ptrPoint = new Point monPoint (10, 3);     // Creation d'un objet dynamique

La première ligne crée un pointeur de type Point, c'est à dire pouvant pointer vers une zone de stockage de deux entiers (x, et y). La deuxième ligne crée le point dynamique monPoint de coordonnées (x=10, et y=3). L'adresse de monPoint est stockée ensuite dans le pointeur ptrPoint.
Voilà nous savons créer un objet dynamique, et il se détruit tout seul à la fin du programme ?
Le point ainsi que le pointeur disparaissent, mais pas l'emplacement mémoire qui a été réservé pour son stockage. Autrement dit vous avez un emplacement mémoire devenu inaccessible car vous n'avez plus accès au pointeur qui désignait cet emplacement, mais en plus cet emplacement ne peut plus être utilisé par l'ordinateur car il est réservé. On appelle celà la fuite de mémoire. Lorsque ce phénomène se reproduit, l'ordinateur finit par planter par quantité de mémoire insuffisante. Un redémarrage de l'ordinateur devient alors nécessaire pour récupérer la mémoire perdue. Imaginez la gêne occasionnée sur des serveurs tournant 24h sur 24h !
Il est donc nécessaire de libérer les emplacements mémoires manuellement avant de quitter le programme.

3. Libérer la mémoire d'un objet dynamique

Pour détruire le point et le pointeur précédent, tout en libérant la mémoire, nous écrivons :

delete ptrPoint;     // Libération de la mémoire et destruction du point et du pointeur

4. Un exemple complet

Nous allons reprendre la classe Point vue précédemment en l'incorporant à notre programme à l'aide de fichiers séparés, ce qui améliore la lisibilité. Voici le premier fichier "Point.h" qui contient les déclarations :

#ifndef POINT_H
#define POINT_H

#include <iostream>

// Déclaration de la classe Point
class Point
{
private:
    int x;
    int y;
public:
    Point(int abscisse = 0, int ordonnee = 0);     // Constructeur
    virtual ~Point();           // Destructeur
    void afficher();
};

#endif     // POINT_H

Il y a des lignes que je ne connais pas : "#ifndef POINT_H", ... !
Pas d'inquiétude, car pour créer la classe Point en fichiers séparés dans CodeBlocks, elles s'ajoutent automatiquement lorsqu'on passe par le menu "File", "New", "Class...". Ignorons les pour le moment, et passons au fichier de définitions :

#include "Point.h"

using namespace std;

// Définitions des fonctions de la classe Point
Point::Point(int abscisse, int ordonnee)     // Constructeur
{
    cout << "Creation d'un point avec le constructeur" << endl;
    x = abscisse;
    y = ordonnee;
}

Point::~Point()     // Destructeur
{
    cout << "Suppression du point (" << x << ", " << y << ")" << endl;
}

void Point::afficher()
{
    cout << "Les coordonnees du point sont (" << x << ", " << y << ")" << endl;
}

Ecrivons maintenant le programme principal "main()"

#include "Point.h"

using namespace std;

Point * ptrPoint;

int main()
{
    void uneFonction();     // On déclare une fonction
    uneFonction();
    Point pt2;
    pt2.afficher();
    delete ptrPoint();
    return 0;
}

void uneFonction()
{
    Point pt1(4, 6);
    pt1.afficher();
    ptrPoint = new Point (2, -3);
    ptrPoint->afficher();
}