Vous êtes sur la page 1sur 64

Les classes en C++

Introduction

Constatations :

 Le hardware progresse plus rapidement que le Software.


 Le progrès en Software est insuffisant.
 En hardware : Conception de composants réutilisables.
 En Software : ce n’est pas toujours le cas
 La conception de composants réutilisables est une voie
vers la création de meilleurs logiciels.
Notion d’objet

Le monde réel est composé d’objets et d’entités qui évoluent d’une manière autonome et qui
interagissent entre eux :
Un animal, une voiture, une machine,…
 Idée : Réaliser des programmes qui modélisent (simulent) le monde réel : Les composants d’un
programme seront des entités/ des objets qui représentent les objets du monde réel : Entité 
objet
La notion d’objet n’est pas nouvelle. Elle date de 1967
 1967 : SIMULA : un langage de programmation orienté vers les applications de simulation des
systèmes discrets fut le premier à avoir introduit la notion de classe
 1976 : SMALTALK a implémenté les concepts d’encapsulation, d’agrégation et d’héritage
De nombreux langages OO ont vu le jour : EIFFEL, OBJECTIVE C, LOOPS
Difficultés : créer une représentation abstraite sous la forme d’objets / entités ayant une existence
matérielle ( chien, voiture, …) ou bien virtuelle (sécurité sociale, temps, ….)
Caractéristiques d’un objet

Un objet est caractérisé par :

 Attributs : Ce sont les données qui indiquent l’état de l’objet

 Méthodes : Ce sont les fonctions qui caractérisent son


comportement. Elles permettent de simuler :
 La réaction de l’objet aux sollicitations extérieures
 L’interaction de l’objet avec les autres objets

 Identité : Chaque objet doit avoir une identité qui permet de


le distinguer des autres objets.
Notion de classe

 Une classe décrit la structure d’un ensemble d’objet de même nature. Plusieurs
chiens seront décrits par une même classe « chien ».
 Instance : Un objet est une instanciation d’une classe.
 Créer une classe est similaire à l’opération de définition d’un nouveau type de
données
 Créer un objet est similaire à la déclaration d’une variable
 Une classe sera composée de :
 Attributs
 Méthodes
Exemple: Pour décrire une classe voiture on sera amené à définir ses attributs qui
sont les composants de la voiture et des méthodes qui sont le comportement de la
voiture tels que « faire tourner le moteur »
Exemple de classe
Concept d’encapsulation des données

Dans la programmation classique (procédurale) un programme est composé de :


 Données
 Instructions
 les données ne sont pas protégées.
 Idée : en POO, chaque objet aura ses propres données à l’intérieur protégées du monde
extérieur. Personne ne pourra les regarder ou bien les modifier sauf autorisation. Si un
utilisateur veut consulter les données de l’objet, il devra appeler les méthodes de l’objet.

 Masquage des données : L’utilisateur n’a pas à connaître la manière dont les données
sont stockées. Il ne peut pas les modifier ou bien les consulter directement. Il doit appeler
les méthodes de l’objet.
Exemple d’encapsulation
Niveau de visibilité

Une classe d’objet peut définir trois niveaux de visibilité pour ses
données ou bien pour ses méthodes :

 Publique : l’accès est permis à tout le monde


 Privé : l’accès est interdit à tous les objets extérieurs
 Protégé : l’accès n’est permis qu’aux héritiers
Concept d’héritage

Dans le monde réel, certains objets ont des choses en commun.


Exemple : Les voitures, les camions, les bus sont tous des véhicules
 il est intéressant de définir une classe « véhicule » et de dire ensuite
qu’une voiture est avant tout un véhicule. Les fonctions et les attributs
de « véhicule » seront aussi fonctions et attributs de « voiture ». Celle-ci
pourra avoir des attributs et des fonctions propres à elle.

On dira que « voiture » est héritière de « véhicule ».

La relation « hérite de » définit des relations de « père à fils » entre les


classes et donc une arborescence dite « arborescence des classes ».
Exemple d’héritage

EST-UN ?
Polymorphisme

 Définition :
 Poly : plusieurs
 Morphisme : Forme

 Faculté d’une méthode à pouvoir s’appliquer à des objets de classes


différentes
 Capacité d’une classe à redéfinir une méthode héritée à partir d’une
classe mère : Surcharge.
 Avantages :
 Lisibilité du code
 Généricité du code
Exemple de polymorphisme
Entités modilisables par une classe

Une classe peut modéliser :


 Entités physiques :
avion, voiture, document, imprimante, …
 Rôles :
employé, employeur, pilote, joueur, enseignant,…
 Incidents / évènements :
Décision, décollage, crash, …
 Interactions :
Contrat de vente, contrat de mariage, divorce, …
Les méthodes d’analyse et de modélisation

Modéliser le monde réel sous la forme d’objets abstraits n’est pas une
tâche facile. Il faut :
 Analyser le monde réel
 Identifier les entités
 Déterminer leurs caractéristiques
 Identifier leurs comportements
 Identifier leurs interactions
 Identifier leurs relations
 Etc.
 il faut adopter et suivre une démarche méthodique pour ne pas se
perdre
Les méthodes d’analyse et de modélisation (2)
Cette méthode doit être indépendante du langage de programmation.

 Années 80 : Méthodes pour organiser la programmation fonctionnelle (Merise),


séparation des données et des traitements.

 Début des années 90 : Apparition de la programmation objet (il faut définir une
méthodologie adaptée), apparition de plus de 50 méthodes entre 1990 et 1995.

 1994 : Consensus sur 3 méthodes :


 la méthode OMT proposée par Rumbaugh
 la méthode BOOCH’93 proposée par Booch
 la méthode OOSE proposée par Jacobson

 Les trois méthodes ont unifié leurs efforts et ont convergé vers une méthode
unique connue sous le nom de :
UML : Unified Modeling Language (Langage de Modélisation Unifié)
Les méthodes d’analyse et de modélisation (3)

 1997 : Définition de la norme UML comme standard de modélisation


des systèmes d’information objet par l’OMG (Object Management
Group)
 UML est employé dans l’ensemble des secteurs du développement
informatique :
 Systèmes d’information
 Télécommunication, défense
 Transport, aéronautique, aérospatial
 Domaines scientifiques
Mais pas seulement : on peut modéliser des comportements
mécaniques, humain, etc.
Diagramme d’UML

Diagrammes structurels / statiques (UML Structure)

 Diagramme de classes (Class diagram)


 Diagramme d’objets (Object diagram)
 Diagramme de composants (Component diagram)
 Diagramme de déploiement (Deployment diagram)
 Diagramme de paquetages (Package diagram)
 Diagramme de structures composites (Composite structure diagram)
Diagramme d’UML (2)

Diagrammes comportementaux / dynamiques (UML Behavior)

 Diagramme de cas d’utilisation (Use Case diagram)


 Diagramme d’activités (Activity diagram)
 Diagramme d’états-transitions (State Machine diagram)
 Diagramme d’interaction (Interaction diagram)
 Diagramme de séquence (Sequence diagram)
 Diagramme de communication (Communication diagram)
 Diagramme global d’interaction (Interaction Overview diagram)
 Diagramme de temps (Timing diagram)
Exercice

Le dessin ci-dessous représente des figures (triangles, carrés ou


cercles) emboîtées. Les triangles contiennent une ou plusieurs figures.
Les carrés ne contiennent rien. Les cercles contiennent exactement
une figure. Les figures possèdent des «côtés». On dira que les cercles
ont un seul côté, les triangles trois côtés et les carrés quatre côtés.

Modéliser un diagramme de classes correspondant à la figure.


Correction
Définition d’une classe

La classe décrit le modèle structurel d’un objet. Elle est composée de :


 Ensemble des attributs (ou champs ou données membres) décrivant sa
structure
 Ensemble des opérations (ou méthodes ou fonctions membres) qui lui sont
applicables.

Une classe en C++ est une structure qui contient :


 Des fonctions membres
 Des données membres

Les mots réservés public et private délimitent les sections visibles par
l’application.
Définition d’une classe (2)
Exemple

class Vehicule
{ private : // membres privées

char matriculation[8]; // données membres privées


float poids;
char* Type;

public : // fonctions membres publiques

void init(char [ ], float, char *);


void affiche();
}; // n’oubliez pas ce ; après l’accolade
Droits d’accès

L’encapsulation consiste à masquer l’accès à certains attributs et méthodes d’une


classe. Elle est réalisée à l’aide des mots clés :

 private: les membres privés ne sont accessibles que par les fonctions membres de
la classe. La partie privée est aussi appelée réalisation.
 protected: les membres protégés sont comme les membres privés. Mais ils sont
aussi accessibles par les fonctions membres des classes dérivées (voir l’héritage).
 public: les membres publics sont accessibles par tous. La partie publique est
appelée interface.

Les mots réservés private, protected et public peuvent figurer plusieurs fois dans la
déclaration de la classe. Le droit d’accès ne change pas tant qu’un nouveau droit n’est
pas spécifié.
Recommandations de style

Pour écrire des programmes claires et faciles à relire et à comprendre,


il vaut mieux adopter quelques conventions de style. On pourrait par
exemple choisir de mettre :

 La première lettre du nom de la classe en majuscule


 La liste des membres publics en premier
 Les noms des méthodes en minuscules
Définition des fonctions membres

En général, la déclaration d’une classe contient simplement les prototypes des fonctions
membres de la classe. Les fonctions membres sont définies dans un module séparé ou plus
loin dans le code source.
 Déclaration à l’extérieur de la classe

class Vehicule
{ private :
char matriculation[8]; // données membres privées
float poids;
char* Type;

public :
void init(char [ ], char *, float); // prototype des fonctions membres
void affiche();
void set_poids(float x){ poids=x; }
};
Définition des fonctions membres (2)
void Vehicule::init(char m[ ], float p, char *t)
{ strcpy(matriculation, m);
Type = new char [strlen(t)+1];
strcpy(Type, t);
poids = p;
}
void Vehicule ::affiche()
{ cout << matriculation << " " << Type << " " <<poids; }

Syntaxe générale :
type_valeur_retournée Classe::nom_fonction ( paramètres_formels )
{… // corps de la fonction }
Définition des fonctions membres (3)
 Déclaration à l’intérieur de la classe
La définition de la méthode peut avoir lieu à l’intérieur de la déclaration de la classe. Dans ce cas, ces fonctions
sont automatiquement traitées par le compilateur comme des fonctions inline.
Exemple
class Exemple
{ private : char indice, info;
public :
void init(char v1, char v2){ indice=v1; info=v2; }
void set_indice (char c) { indice = c; } // fonction inline
char get_indice () { return indice; } // fonction inline
void affiche();
};
inline void Exemple::affiche()
{ // fonction inline : La visibilité d’une fonction inline est restreinte au module dans lequel elle est définie.
cout << « Indice = " << indice << endl; }
Instanciation d’une classe

De façon similaire à une struct ou à une union, le nom de la classe représente un


nouveau type de donnée. On peut donc définir des variables de ce nouveau type;
on dit alors que vous créez des objets ou des instances de cette classe.

Exemple

Vehicule v1; // une instance simple (statique)


Vehicule *v2; // un pointeur (non initialisé)
Vehicule Groupe[20]; // un tableau d’instances
v2 = new Vehicule; // création (dynamique) d’une instance
Utilisation des objets

Après avoir créé une instance (de façon statique ou dynamique) on peut
accéder aux attributs et méthodes de la classe. Cet accès se fait comme
pour les structures à l’aide de l’opérateur . (point) ou -> (flèche).

Exemple

v1.init("00779", 3, "BMW");
v2->init("00778", 4.7, "WV");
Groupe[0].init("007339", 6, "SEAT");
v1.affiche();
v2->affiche();
Groupe[0].affiche();
v1.set_poids(0);
Exercice

 Nombre complexe

Un objet complexe doit contenir deux composantes réelles et doit répondre aux
fonctions suivantes :
 initialiser un nombre complexe
 additionner deux nombres complexes
 soustraire deux nombres complexes
 multiplier deux nombres complexes
 afficher un nombre complexe
 etc.

 Attributs : Deux réels : x et y


 Méthodes : Initialiser, Additionner , Soustraire, Multiplier, afficher
Correction
class complexe void complexe ::soustraire(complexe z)
{ public: { x = x - z.x ;
float x,y ; y = y - z.y ; }
void init (float a=0, float b = 0);
void ajouter (complexe z); void complexe ::multiplier(complexe z)
void soustraire (complexe z); { x = x*z.x - y*z.y ;
void multiplier (complexe z); y = x*z.y + y*z.x ; }

void afficher ( ); };
void complexe :: init(float a , float b) void complexe::afficher( )
{ if (y>=0)
{ x = a;
cout <<x<< « +i »<<y ;
y=b;}
else
void complexe::ajouter(complexe z)
cout <<x<< « -i »<<-y ;
{ x = x + z.x ;
}
y = y + z.y ; }
Exercice

 Pile d’entiers

Un objet Pile doit répondre aux fonctions suivantes :


 Initialiser une pile
 Empiler un élément sur la pile
 Dépiler un élément de la pile

Pour cet exemple, nous allons supposer que les éléments à empiler sont de type
entier et nous allons utiliser un tableau linéaire pour l’implémentation.
Correction
//----------------- init ----------------------------- //----------------- push -----------------------------
class pile int pile::push (int x)
void pile::init ()
{ int tab [100]; { if (!full())
int k; { k=0 ; { tab[k++] = x;
// indice dans tab de la première position libre max = 100; return 1;
int max; } } else return 0;}
// nombre maximum de places dans la pile //----------------- pop -----------------------------
//----------------- full ----------------------------- int pile::pop ( )
bool pile::full() {
public:
{ return (k >= max ) ; } if ( !empty () )
void init (); { return tab[--k];
int push (int x); }
int pop (); //----------------- empty --------------------------- else
int full (); bool pile::empty() return 0;
int empty (); { return (k == 0 ) ; }
};
}
Fonctions constantes
 Certaines méthodes d’une classe ne doivent (ou ne peuvent) pas modifier les valeurs des données
membres de la classe, ni retourner une référence non constante ou un pointeur non constant d’une
donnée membre. On dit que ce sont des fonctions membres constantes.
 Ce type de déclaration renforce les contrôles effectués par le compilateur et permet donc une
programmation plus sûre sans coût d’exécution.
Exemple
class MaClasse
{ private :
int indice;
float info;
public :
void set_indice (int n) { indice = n; }
// méthodes constantes
int get_indice() const { return indice; }
void affiche() const;
};
inline void MaClasse::affiche() const
{ cout << "Indice = " << indice << endl; }
Fonctions constantes (2)
Une fonction membre const peut être appelée sur des objets constants ou pas, alors qu’une
fonction membre non constante ne peut être appelée que sur des objets non constants.

Exemple
const MaClasse mc1; // une constante
mc1.affiche(); // OK
mc1.set_indice(5); /* ERREUR: seule les fonctions const peuvent être appelées
pour un objet constant*/
MaClasse mc2;
mc2.affiche(); // OK
mc2.set_indice(5); // OK
Surcharge d’une méthode par une méthode
constante
Une méthode déclarée comme constante permet de surcharger une méthode non constante avec le
même nombre de paramètres du même type.
Exemple
class Chaîne
{ private :
char *mach;
public :
void init(char *ch = "");
// etc ...
char nieme (int n); // (1)
char nieme (int n) const; // (2)
// etc...
};
S’il n’y a pas le qualificatif const dans la deuxième méthode, le compilateur génère une erreur
(« Chaîne::nieme() cannot be redeclared in class").
Surcharge d’une méthode par une méthode
constante (2)

Cette façon de faire permet d’appliquer la deuxième méthode nieme() à des


objets constants et la première méthode nieme() à des objets variables :

int main()
{
Chaîne ch1;
ch1.init("machaine");
const Chaîne ch2;
ch2.init("machaine2");
cout << ch1.nieme(1); // appel de la méthode (1)
cout << ch2.nieme(9); // appel de la méthode (2)
}
Constructeurs

Les données membres d’une classe ne peuvent pas être initialisées; il faut donc
prévoir une méthode d’initialisation de celles-ci (voir la méthode init de l’exemple
précédent). Si l’on oublie d’appeler cette fonction d’initialisation, le reste n’a plus de
sens et il se produira très certainement des surprises fâcheuses dans la suite de
l’exécution. De même, après avoir fini d’utiliser l’objet, il est bon de prévoir une
méthode permettant de détruire l’objet (libération de la mémoire dynamique ...).

 Le constructeur est une fonction membre spécifique de la classe qui est appelée
implicitement à l’instanciation de l’objet, assurant ainsi une initialisation correcte de
l’objet. Ce constructeur est une fonction qui porte comme nom, le nom de la classe et
qui ne retourne pas de valeur (pas même un void).
Constructeurs (2)

Il existe trois types de constructeurs :

 Constructeur par défaut


 Constructeur à un ou plusieurs paramètres
 Constructeur de copie

Une classe peut avoir plusieurs constructeurs.


Constructeur par défaut
On appelle constructeur par défaut un constructeur n’ayant pas de paramètre ou ayant des valeurs
par défaut pour tous les paramètres. Si le concepteur de la classe ne spécifie pas de constructeur, le
compilateur génèrera un constructeur par défaut.

Exemple

class MaClasse
{ public :
MaClasse ( ); // constructeur par défaut
// ...
private :
int indice;
};

MaClasse :: MaClasse ( )
{ indice = 0; }
Constructeur paramétré
class MaClasse
{
public :
MaClasse (int i=0); // constructeur à un paramètre
// ...
private :
int indice;
};

MaClasse :: MaClasse ( int a )


{
indice = a;
}
Constructeur avec paramètres et surcharge des
constructeurs
Comme les autres fonctions, les constructeurs peuvent être surchargés.

class MaClasse
{ public :
MaClasse ( ); // constructeur par défaut
MaClasse ( int a ); // constructeur à 1 paramètre
private :
int indice;
};

Le constructeur est appelé à l’instanciation de l’objet. Il n’est donc pas


appelé quand on définit un pointeur sur un objet.
Constructeur avec paramètres et surcharge des
constructeurs (2)
Exemple
MaClasse mc1; //correct, appel du constructeur par défaut

MaClasse mc2 ( 3 ); //correct, appel du constructeur à 1 paramètre

MaClasse *ptr1, *ptr2; //correct, pas d’appel aux constructeurs

ptr1 = new MaClasse ; //appel au constructeur par défaut

ptr2 = new MaClasse (2); //appel du constructeur à 1 paramètre

MaClasse tab1[10]; // chaque objet du tableau est initialisé


// par un appel au constructeur par défaut

MaClasse tab2[3] = {MaClasse (1), MaClasse (2), MaClasse (3) }; //initialisation des 3 objets du tableau par les
//nombres 1, 2 et 3
Destructeur

De la même façon que pour les constructeurs, le destructeur est une fonction membre
spécifique de la classe qui est appelée implicitement à la destruction de l’objet. Ce
destructeur est une fonction qui :

 porte comme nom, le nom de la classe précédé du caractère (tilda ~)


 ne retourne pas de valeur (pas même un void )
 n’accepte aucun paramètre (le destructeur ne peut donc pas être surchargé)
Destructeur (2)
Exemple

class MaClasse
{ public :
// ...
~MaClasse ( );
private :
// ...
};

MaClasse :: ~MaClasse ( )
{ // ... }

Comme pour le constructeur, le compilateur génèrera un destructeur par défaut si le


concepteur de la classe n’en spécifie pas un.
Exercice
Dans cette version de l’implémentation d’une pile, nous allons définir un constructeur qui aura pour
rôle d’allouer un espace mémoire et d’initialiser l’indice sommet. Les autres fonctions restent
inchangées.
class pile
{ int *tab ; // pointeur sur le début de la pile
int sommet ; // indice première position libre
int max ; // nombre max de places

public:
pile ( int taille = 100); // constructeur
~pile ( ) ; // destructeur
bool full ();
bool empty ();
bool push (int x);
int pop ( ); };
Constructeur de copie

 Présentation du problème

Une variable peut être créée de quatre manières différentes :

 Déclaration : int a ;
 Par new : p = new int;
 Initialisation : int b = a;
 Paramètre d’une fonction : A chaque paramètre est créée sur la pile une
variable qui recevra une copie du paramètre. Cette variable locale sera
détruite automatiquement à la sortie de la fonction. Afficher(bidon objet)
Constructeur de copie (2)

Dans les deux premiers cas, le constructeur d’une classe est appelé
automatiquement. Par contre il n’est pas appelé dans le troisième et le
quatrième cas. Le destructeur quant à lui est appelé dans tous les cas.

 On doit créer un constructeur spécial dit « constructeur de


copie » qui sera appelé uniquement dans le 3ème et le 4ème cas. Ce
constructeur portera le même nom que le constructeur standard mais
avec un paramètre qui devra être une référence à un objet de la
même classe :
MaClasse ( MaClasse & ) ;
Constructeur de copie (3)
~MaClasse ( ) // destructeur
Exemple
{

class MaClasse cout << "Entrée dans destructeur " <<endl;


{ }
int data; void fonction_test( MaClasse objet )
{
public:
cout << "Entrée dans fonction_test "<<endl;
MaClasse (int k=0) // constructeur d'initialisation cout<<objet.data<<endl;
{ }
data = k; };
cout << "Entrée dans constructeur d'initialisation " <<endl;
int main ( )
}
{
MaClasse ( MaClasse &objet) // constructeur de copie
{ MaClasse obj1(100), obj2(200), obj3=obj1;
data = objet.data;
cout << "Entrée dans constructeur de copie " <<endl; obj1.fonction_test (obj2);
}
}
Constructeur de copie (4)

Le programme imprimera les lignes suivantes :

Entrée dans constructeur d'initialisation // généré par MaClasse obj1(100)


Entrée dans constructeur d'initialisation // généré par MaClasse obj2(200)
Entrée dans constructeur de copie // généré par MaClasse obj3=obj1
Entrée dans constructeur de copie // généré par : obj1.fonction_test (obj2)
Entrée dans fonction_test
Entrée dans destructeur // destruction de l’argument objet
// à la sortie de la fonction
Entrée dans destructeur // destruction de obj3
Entrée dans destructeur // destruction de obj2
Entrée dans destructeur // destruction de obj1
Exercice
Scénario 1

Objet Objet
Date_initiale Date_copiée
jour jour
mois mois
année année

15 09 2021
Exercice (2)
Scénario 2
Objet
Date_initiale
jour
mois 15 09 2021
année

Objet
Date_copiée
jour
15 09 2021 mois
année
Exercice (3)
class MaDate
{ private:
int *jour, *mois, *annee;
public:
MaDate (int,int,int); //Constructeur par défaut
MaDate (const MaDate &); //Constructeur de copie
~MaDate ( ); //Destructeur

void modifier_Date (int j,int m,int a)


{ *jour=j; *mois=m; *annee=a; }
void afficher_Date ( ) const
{ cout<<*jour<<" "<<*mois<<" "<<*annee<<endl; }

int get_Jour ( ) const { return *jour; }


int get_Mois ( ) const { return *mois; }
int get_Annee ( ) const { return *annee; } };
Classes imbriquées
Il est possible de créer une classe par une relation d’appartenance : relation « a un » ou « est composée
de »  un membre d’une classe peut être un objet d’une autre classe
Exemple : une voiture a un moteur, a des roues ...

class Produit { /* ... */ };

class Vendeur { /* ... */ };

class Magasin
{ public:
// ....
private:
Vendeur ListeVend [10];

Produit ListeProd [100];


// ....};
Affectation et initialisation
Le langage C++ fait la différence entre l’initialisation et l’affectation d’une variable :
 L’initialisation est une opération qui n’a lieu qu’une fois immédiatement après que
l’espace mémoire de la variable ait été alloué. Cette opération consiste à donner une
valeur initiale à l’objet ainsi créé.
 L’affectation consiste à modifier la valeur d’une variable (et peut avoir lieu plusieurs
fois).

int main ( )
{
int n = 100 ; // c’est une initialisation
n = 200 ; // c’est une affectation
//…..
}

Initialiser une variable simple est facile par contre initialiser un objet qui est composé de
membres qui peuvent eux mêmes être des objets peut poser quelques petits problèmes.
Liste d’initialisation d’un constructeur
Lorsqu’on a des classes imbriquées, il peut y avoir un problème lors de l’appel du constructeur des différentes
classes.
class Composant
{ int att1 ;
float att2,
public :
Composant ( int a=0, float b=0) { att1 = a ; att2 = b;} …
};
class Composite
{ const int x;
int y;
Composant z;
public:
Composite(int a, int b, int c, float d); // Constructeur de Composite
~Composite ( ); // Destructeur de Composite
};
Liste d’initialisation d’un constructeur (2)
Composite :: Composite (int a, int b, int c, float d)
{ x=a ; // ERREUR: l’affectation à une constante est interdite
y=b // OK : affectation
// et comment initialiser l’objet membre z ???}
Comment initialiser la donnée membre constante x et appeler le constructeur de la classe Composant ?
Réponse : la liste d’initialisation
La phase d’initialisation de l’objet utilise une liste d’initialisation qui est spécifiée dans la définition du constructeur.
Syntaxe : nom_classe::nom_constructeur(args...) : liste_d’initialisation
{ // corps du constructeur }

Composite::Composite ( int a, int b, int c, float d ): x(a), y(b), z( c,d )


{ // y=b; }

x( a ) x = a
y( b ) y = b
z( c,d ) appel du constructeur de la classe Composant : Composant (c,d)
Pointeur “this”
Toute méthode d’une classe MaClasse a un paramètre caché : le pointeur this qui contient
l’adresse de l’objet qui l’a appelé. Il est implicitement déclaré et initialisé avec l’adresse de
l’objet sur lequel la méthode est appelée.

Il peut être explicitement utilisé :

classe MaClasse
{ int attribut ;

public:
int fonction_membre1( )
{
return this  i; //équivalent à : return i ;
}
};
Les membres statiques

Ces membres sont utiles lorsqu’on a besoin de gérer des données communes aux instances d’une
même classe. On peut avoir des données statiques et des fonctions statiques.

 Données membres statiques


Si l’on déclare une donnée membre comme static, elle est commune à tous les objets. Elle existe même
si aucun objet n’a été créé et elle aura la même valeur pour toutes les instances de cette classe. Elle est
accessible en spécifiant soit le nom de l’objet soit celui de la classe.
class MaClasse
{ static int a;
int b ;
public:
MaClasse ( ) { a++; /* ... */ }
~MaClasse ( ) { a--; /* ... */ }
};
Les membres statiques (2)
 Fonctions membres statiques
De même que les données membres statiques, il existe des fonctions membres statiques. Une fonction static ne peut
accéder qu’aux membres statiques et ne peut pas être surchargée. Elle existe même s’il n’y a pas d’instance de la
classe.
class MaClasse
int main ( )
{ static int a ; {
int b; MaClasse x, y, z ;
x.affiche ( ) ; //affiche 3
public:
}
MaClasse ( ) { a++; /* ... */ }
~MaClasse ( ) { a--; /* ... */ }
static void affiche()
{ cout << a << endl; }
};
int MaClasse : : a = 0; // initialisation du membre static (en global)
Classes et fonctions amies

 Une classe peut déclarer « amie » une autre classe ou des fonctions
externes.

Une classe ou une fonction peut toucher les membres privées ou


protégés de son « ami».

 C’est le mot clé friend qui permet de déclarer l’amitié entre classes.
 C’est une infraction aux règles d’encapsulation pour des raisons
d’efficacité.
Fonctions amies
Exemple

class MaClasse

{
friend void visualiser (MaClasse ); // fonction amie
int a ;
public :
// ...
};

void visualiser(MaClasse n)
{
cout << n.a ;
}
Classes amies
Exemple

class Fenetre { // déclaration de la classe Fenetre };

class Ecran
{ friend class Fenetre;
public:
//...
private :
//...
};

Les fonctions membres de la classe Fenetre peuvent accéder aux membres non-
publics de la classe Ecran.

Vous aimerez peut-être aussi