Title: Cours 2
1Cours 2
Les classes et les objets (suite)
2Plan du cours 2
- Objets et membres constants
- Pointeur this
- Surcharge dopérateurs
- Membres statiques
3I. Objets et membres constants
- Mot clé const
- Mot clé du langage spécifiant quaucune
modification dun objet, dune variable ou dun
pointeur nest permise. - La signification du const dans la signature dune
fonction membre dune classe dépend de sa
position.
4const (suite)
- Attribut la valeur est constante, fixée à la
création de lobjet. - Fonction membre const ne modifie pas lobjet
courant, peut seulement accéder à linformation. - Objet const appel seulement de fonctions membres
const.
5Attribut constant
- Question Comment initialiser un attribut
constant? - Réponse Par le biais dune liste
dinitialisation - class C
- public
- C()
- ...
- private
- const int x
- ...
-
- CC()
- x(0)
-
- ...
6II. Le pointeur this
- Le mot this est un mot réservé contenant
ladresse de lobjet courant. - Ce pointeur sert, entre autres, à retourner une
référence à cet objet pour les appels en
cascade.ex a b c d - Il ne faut jamais retourner une référence à une
variable locale.
7II - Surcharges dopérateurs
- Surcharge des opérateurs binaires, unaires,
opérateur assignation - Commutativité et fonctions globales
8Introduction
La surcharge (ou surdéfinition) dopérateur est
un concept qui permet dimplémenter une fonction
ou un opérateur de différentes façons sans en
changer la méthode dappel (signature).
9Besoin de la surcharge dopérateurs
- En C/C, il existe des variables de types
simples int, float, double, sur lesquelles on
peut effectuer des opérations arithmétiques. - En C/C, il nexiste aucun type de base string,
doù le besoin de créer une classe string pour
traiter les chaînes de caractères. - Cette classe string posséderait tous les
opérateurs définis pour un type tel que un entier
ou un double (, , , etc).
10Application de la surcharge dopérateurs
- string S1(allo ), S2(le monde), S3
- S3 S1 S2
- S3 S1 a tous
- S21 a
- S23 r
Cet exemple est rendu possible grâce à
lutilisation de la surcharge des opérateurs
et pour la classe string.
11Surcharges dopérateurs
- Consiste à redéfinir la fonctionnalité dun
opérateur tel que , -, ou pour une classe. - Il faut bien comprendre le fonctionnement de
lopérateur. - Lordre de priorité est conservé.
- Lobjet est toujours lopérande de gauche.
- Les opérateurs gardent leur nombre de paramètres
et ne peuvent avoir de paramètres par défaut. (
opérateurs binaires et unaires) - Il nest pas possible de créer de nouveaux
opérateurs.
12Surcharges dopérateurs
Ne pouvant être surchargés
Pouvant être surchargés
. ? sizeof
- / () lt gt - /
! -- -gt , gtgt ltlt ! lt gt \ ltlt gtgt
new delete
13Surcharges dopérateurs binaires
- Opérateur à deux opérandes.
- Il doit y avoir une opérande à gauche et à droite
du symbole de lopérateur.
14Opérateurs binaires
- string S1(allo), S2(le monde), S3
- S3 S1S2 // équivalent à S1.operator(S2)
- operator() est une fonction membre de la classe
string, car S1 est un objet de la classe string. - Retourne un objet string.
15La classe string string.h
class string public // Constructeurs str
ing(char ch) string (const char cstring)
string() delete buffer //
Opérations ... string operator (const
string) const private int strLength int
bufferLength char buffer ...
16Implémentation de lopérateur de string
string stringoperator(const string cstr)
const string Concat Concat this //
surcharge de lopérateur Concat cstr //
surcharge de lopérateur return Concat
Remarque lopérateur est défini en fonction de
lopérateur
17Implémentation de lopérateur de string (suite)
- Que se passe-t-il ?
- string S1(allo), S2
- S2 S1 tous // ici il y a une conversion
- // implicite qui est réalisée
- S1.operator(tous)
- Conversion implicite
- On sattend à une opérande de type string
- On a une opérande de type char
- Il existe un constructeur qui accepte ce type de
paramètre - On construira donc un objet de type string en lui
passant la chaîne - On pourra alors appliquer lopérateur aux deux
opérandes -
18Conversion implicite de type
- Il faut se méfier des conversions implicites, C
peut en faire à des endroits où on ne sy attend
pas - On peut empêcher quun objet soit créé par une
conversion implicite il suffit dajouter
explicit avant la déclaration du constructeur - Ainsi, si on déclare le constructeur de la
manière suivante -
- explicit string (const char cstring)
-
- on pourra empêcher la construction dun string
dans les cas suivants - string S1, S2
- S allo
- S2 S1 allo
-
-
19Implémentation de lopérateur de string (suite)
- Si on déclare le constructeur explicit,
linstruction S2 S1 allo nest plus
acceptée parce que lopérateur naccepte que des
opérandes de type string. - Dans ce cas, pour que linstruction soit valide,
il faut ajouter une autre définition de
lopérateur
20Implémentation de lopérateur de string (suite)
class string public // Constructeurs exp
licit string(char ch) explicit string (const
char cstring) string() delete
buffer // Opérations ... string operator
(const string) const string operator
(const char cstr) const private int
strLength int bufferLength char buffer ...
21Commutativité et fonctions globales
- Ces derniers exemples de lopérateur prennent
comme supposition que lopérateur de gauche est
un objet string. - Cependant, ceci nimplique pas que cet opérateur
est commutatif
22Opérateur non commutatif
- string S1(allo), F2(le monde), F3
- char A tous
- S3 S1 A // équivalent à S1.operator(A)
- Cet exemple utilise la surcharge
- string operator (const char) const
- Mais
- S3 A S1 //équivalent à A.operator(S1)???
23Commutativité et fonctions globales (suite)
- Si lon désire définir des opérateurs qui accepte
autre chose quun objet string à gauche, et un
objet string à droite de lopérateur, il faut se
définir des fonctions globales pour permettre
cette commutativité. - Exemple de surcharge globale de type char
string - string operator(const char A, const string B)
24Commutativité et fonctions globales (suite)
- Remarque
- Si on définit lopérateur comme un opérateur
global, et quon exclut pas la conversion
implicite à partir dun char lors de lappel du
constructeur, on pourrait se contenter dune
seule définition - string operator(const string A, const string
B)
25Fonctions amies
- Problème dans certains casLa fonction globale
na pas le droit daccéder au données privées de
la classe - Solutions
- Lopérateur global accède aux données privées par
le bien de fonctions membres publiques (peut être
inefficace dans certains cas) - On déclare la fonction globale comme étant
amie - friend string operator (char, const string )
26Fonctions amies (suite)
- Attention les fonctions amies violent le
principe dencapsulation. À moins de ne pouvoir
faire autrement, il vaut mieux les éviter - Dans le cas de la classe string, on peut
léviter, en définissant une fonction globale qui
prend en paramètre deux objets de type string - string operator(const string, const string)
- Dans ce cas, il faut bien entendu que le
constructeur accepte la conversion implicite - Dans certains cas, on peut éviter de déclarer une
fonction amie en nutilisant que des fonctions
membres de la classe pour accéder aux attributs
de lobjet, si elles sont suffisantes pour la
définition de lopérateur
27Surcharges dopérateurs unaires
- Opérateur ayant un seul paramètre.
- Lunique argument est implicitement lobjet
lui-même.
Rational operator () Rational
Rationaloperator () numerdenom retur
n (this) Exemple dutilisation Rationa
l F(2,3) F
28Surcharges de lopérateur dassignation ()
- Si lopérateur nest pas surchargé, le
compilateur en génère un automatiquement.
Cependant, lassignation se fait attribut par
attribut. - Lopérateur par défaut peut causer de sérieux
problèmes si lobjet contient des membres
construits par allocation dynamique.
29Fonctions membres par défaut
- Dans une classe, même si le programmeur ne les
définit pas, il y a toujours - Un constructeur par défaut sil nexiste aucun
autre constructeur. - Un constructeur de recopie (attribut par
attribut) - La surcharge de lopérateur par défaut(
attribut par attribut) est créée si une
instruction fait appel à cet opérateur. - Un destructeur par défaut
30Attention !
- Si votre classe a un attribut qui est un
pointeur et alloue de lespace mémoire
dynamiquement, il faut absolument définir - Un constructeur de recopie
- Lopérateur
- Et un destructeur
- Et surtout ne pas utiliser les fonctions par
défaut.
31Exemple de surcharge dopérateur et de
constructeur copie
- Dans la classe string, on a retiré le
- constructeur copie et la surcharge de lopérateur
- class string
-
- public
- string(char ch)
- string(const char)
- string()
- . . .
- private
- char buffer
- int length
-
32Exemple de surcharge dopérateur
buffer length4
a
buffer length4
b
33Exemple de surcharge dopérateur
- string stringoperator(const string rhs)
-
- if( this ! rhs)
-
- if(bufferLength lt rhs.length()1)
-
- delete buffer
- bufferLengthrhs.length()1
- buffer new charbufferLength
-
- strLengthrhs.length()
- strcpy(buffer,rhs.buffer)
-
- return this
-
34IV Membre statique
- Un attribut static nexiste quen une seule copie
pour tous les objets dune classe. - Un attribut static est un espace commun à tous
les objets instanciés. - Lespace mémoire dune variable de classe existe
même si aucun objet na été déclaré. - Cette variable est accessible via les fonctions
membres ou par lentremise de lopérateur de
résolution de portée . - Linitialisation dune variable de classe ne se
fait pas dans le constructeur
35Fonction de classe static
- Une fonction de classe static ne peut accéder
quaux membres static dune classe. - On peut appeler une fonction de classe sans
déclarer dobjet par lopérateur de résolution de
portée . - Les règles dencapsulation demeurent les mêmes.
36Variable de classe et fonction de classe
statiques
- La classe Sphere possède la variable static
nbSphere, qui conserve - le nombre total de sphères créées dans le
programme. - class Sphere
- public
- ...
- static int getNbSphere() return nbSphere
- ...
- public
- ...
- static int nbSphere
- ...
-
- // Initialisation dans sphere.cpp
- int SpherenbSphere 0
Fonction de classe