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.
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.
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
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();
}