Classes-I : sommaire
Classes-I 1
Classes-I : définitions
Comment définir un tel objet ???
Classes-I 2
-
Primitive de base pour l'encapsultation et l'abstraction des
données en C++.
- Type défini par l'utilisateur, encapsulant un ensemble
de données (attributs) avec différents services
(méthodes).
- Mêmes possibilités que les structures : allocation
dynamique, arg. de fonction, pointeurs, ....
class compte { |
int solde ; |
char nom_proprio[50]; |
void maj_solde(int); |
... |
void deposer(int); |
void retirer(int); |
... |
};
|
Classes-I 3
-
Aussi appelés ``Données membres''.
- Similaire aux champs d'une structure.
- Peuvent être de type prédéfini, ou défini par l'utilisateur
(via class, struct, ou typedef).
- Accès similaire aux champs d'une structure : utilisation de
'.' ou de '
->
'.
-
Les méthodes sont les opérations applicables à toute instance de
la classe.
- Sont appelées aussi ``Fonctions membres''.
- Une structure ou une union peuvent comporter également des
fonctions membres (mais préférer classes à structures).
- Accès similaire aux champs d'une structure : utilisation de
'.' ou de '
->
'.
Classes-I 4
-
Un objet est une instance de classe.
- Attribut : une copie propre à chaque instance,
- Méthode : un seul exemplaire, applicable à n'importe quelle
instance.
Déclarations et définitions
compte c1; |
compte c2 = compte() ; // idem que c1 |
compte *pt1, *pt2=&c2 ; // pointeurs |
compte& ref = c1 ; // référence |
compte tab[10];// tableau d'instances |
|
compte c3() ;// !! CECI DECLARE 1 FONCTION!!
|
Allocation dynamique
pt1 = new compte ; |
pt2 = new compte[7] ; |
delete pt1 ; |
delete [] pt2 ;
|
Classes-I 5
Contrôle d'accès aux membres d'une classe (1) |
-
Spécifié dans la DECLARATION de la classe
Exemple (compte.hh) :
class compte { |
private : |
int solde ; |
char nom_proprio[50] ; |
void maj_solde(int); |
public : |
void retirer(int) ; |
void deposer(int) ; |
int getSolde(void) ; |
... |
};
|
Classes-I 6
Contrôle d'accès aux membres d'une classe (2) |
-
Trois degrés d'encapsulation :
-
private : seules les fonctions membres de la classe
peuvent référencer les membres privés,
- protected : seules les fonctions membres de la
classe ou d'une classe dérivée peuvent
référencer les membres protégés,
- public : membres publics peuvent être référencés de
n'importe où
-
Ces degrés sont optionnels, répétables, et déclarables dans
un ordre quelconque
- Les membres d'une classe sont privés par défaut.
- (pour une structure, les membres sont publics par défaut.)
Classes-I 7
Contrôle d'accès aux membres d'une classe (3) |
Règle pratique : définir les données en private
(ou protected), et définir en public des méthodes
pour les services de la classe.
Accès illicites
int main() { |
compte c1; |
c1.solde = 1000 ; // Erreur : champ privé |
cout << c1.nom_proprio ; // idem |
c1.maj_solde(-100); // idem |
}
|
Accès licites
int main() { ... |
if (c1.getSolde() >= retrait) |
c1.retirer(retrait) ; |
i = pt-> getSolde() ; |
} // getSolde() et retirer() sont publiques
|
Classes-I 8
Fonctions membres : déclaration |
-
Chaque méthode DOIT être déclarée dans la définition
de la classe.
- Elle peut éventuellement être définie en même temps.
Exemple (compte.hh) :
class compte { |
private: |
int solde ; |
char nom_proprio[50] ; |
void maj_solde(int); |
public: |
int retirer(int somme);// définie ailleurs |
int getSolde(void) { // décl. avec définition |
return solde ; |
} |
... |
} ;
|
Classes-I 9
Fonctions membres : définition |
Exemple (compte.cc) :
#include "compte.hh" |
int compte::retirer(int somme) { |
maj_solde(-somme) ; |
}
|
-
Le nom de la fonction membre est préfixé par le nom de la classe
suivi de '::'.
- Une fonction membre accède directement aux membres de
l'objet sur lequel elle s'applique.
Remarque : dans le corps d'une méthode, on peut accéder
aux attributs privés de toutes les
instances de sa classe qui sont définies
(ou accessibles) dans ladite méthode.
int compte::method(compte c) { |
int d = (solde - c.solde) ; // OK |
compte *tmp = new compte ; |
tmp-> solde = solde ; // OK |
... |
}
|
Remettre un exemple avec les structures et unions comportant des
fonctions membres.
Classes-I 10
Exemples de fonctions membres |
-
Gestion de la classe : constructeur,
destructeur, conversion, affectation, et autres
opérateurs.
Pour contrôler la création, l'initialisation,
l'affectation et la destruction des instances.
- Implantation : méthodes réalisant les fonctionnalités
de la classe.
- Accès : méthodes d'accès aux données membres de la
classe.
- Auxiliaire : méthodes "cachées" aidant dans l'implantation
de la classe.
Classes-I 11
Constructeur/Destructeur de classe
-
Constructeurs
- Destructeur
Classes-I 12
Classes-I : Constructeur (1)
Classes-I 13
Déclaration
class String { |
int len ; char * pt ; |
public: |
String(int l=0) { // Constr. 1 |
len = l; |
pt = new char[l+1]; pt[0]='\0'; |
} |
String(const char *) ; // Constr. 2 |
};
|
Définition
String::String(const char * ch) { |
len = strlen(ch); |
pt = new char[len+1]; |
strcpy(pt,ch); |
}
|
Utilisation
String s=3, s1(10); // Appel de Constr. 1 |
String s2("bonjour"); // Appel de Constr. 2 |
String s3="hello"; // Appel de Constr. 2 |
int i(1), j=3; // Constr. type prédéfini
|
Classes-I 14
Constructeur et données membres |
-
Si des attributs d'une classe sont des instances,
leurs constructeurs respectifs sont invoqués AVANT celui
de la classe les contenant (et dans l'ordre de déclaration).
class compte { |
int solde ; |
String nom_proprio ; |
public: |
compte(int depot=0) { |
solde = depot ; |
} |
}; |
|
... |
compte c ; |
// appel du constr. de String (pour |
// nom_proprio) puis du constr. de compte
|
Classes-I 15
Liste d'initialisation d'un constructeur |
-
Chaque constructeur peut spécifier une liste d'initialisations
qui précise comment chaque donnée membre doit être initialisée.
class compte { |
int solde ; |
String nom_proprio ; |
public: |
compte(char* nom) : nom_proprio(nom), |
solde(0) {} |
};
|
- Usage OBLIGATOIRE pour initialiser un membre :
-
qui est défini constant, ou
- qui est de type référence, ou
- qui est une instance d'une classe n'ayant pas de
constructeur sans argument.
- * Utiliser le plus possible.
Classes-I 16
-
Par défaut, une classe contient implicitement : un constructeur
sans argument et un constructeur par recopie membre à membre
(bit à bit).
class Point { |
int x, y; |
}; |
|
int main(void) { |
Point p0 ; // Constructeur ss argument |
|
Point p1(p0); |
// Construction de p1 par |
// recopie membre à membre de p0 |
Point p2 = p0; |
// idem que p1 |
... |
}
|
-
MAIS dès qu'un constructeur est déclaré, le constructeur sans
argument n'existe que s'il est défini EXPLICITEMENT.
Classes-I 17
Classes-I: Destructeur (1)
-
Rôle principal : effectuer les opérations nécessaires avant la
destruction d'une instance (typiquement, libération de mémoire
allouée par le constructeur),
- Appelé implicitement par le compilateur à chaque
fois qu'une instance sort du champ de sa définition (ou détruite
par delete),
- Méthode de même nom que sa classe précédée d'un
~, sans argument et ne retournant
aucun résultat,
classX::~classX()
- * Généralement public.
- * UN SEUL destructeur par classe.
Classes-I 18
Exemple
class String { |
int len; char * pt ; |
public: |
String(char *st) { |
len = strlen(st) ; |
// alloc. tab[len+1] de char |
pt = new char[len+1] ; |
strcpy(pt,st) ; // recopie |
} |
// libération de la mémoire occupée par pt |
~ String() { delete [] pt; } |
} ;
|
Classes-I 19
Destructeur et données membres |
-
Si des attributs d'une classe sont des instances (d'autres
classes), leurs destructeurs respectifs sont invoqués APRES celui
de la classe les contenant (et dans l'ordre inverse de
déclaration).
class compte { |
int solde ; |
String nom_proprio ; |
public: |
compte(char *) ; |
~ compte() ; |
... |
} ; |
... |
compte *c = new compte("Paul") ; |
... |
delete c ;
// appel du destructeur de compte, |
// puis de celui de String pour nom_proprio
|