SlideShare une entreprise Scribd logo
Cours C++ (2002)
semaine 2
jour 1
Plan du jour
 Pointeurs, références et copies d’objets : la
suite
 Pointer to members
 Surcharge d’opérateur
 Création dynamique d’objets
 Dynamic binding
 RTTI
Cours semaine 2 jour 1 Cours C++ 2
Cours semaine 2 jour 1 Cours C++ 3
Pointeurs…
 Dans le cours précédent, nous avons parlé :
 Des pointeurs, un type de base en C et C++ !
 Des passages par références (avec les pointeurs)
et des passage par valeurs (avec des copies des
valeurs)
 Des copies d’objets pour que ceux-ci puissent
être passés par valeur (copy-contructor)
 C++ offre encore une possibilité de
travailler avec les pointeurs dans les classes
Cours semaine 2 jour 1 Cours C++ 4
Pointeurs… (2)
 Un classe est une structure qui définit un
ensemble :
 de variables, généralement privées,
 De méthodes ou de signatures de méthodes, qui
peuvent être publiques, protégées ou privées
 Un pointeur permet de désigner des
variables, il permet également de désigner
des fonctions
Cours semaine 2 jour 1 Cours C++ 5
Pointeurs… (3)
int i = 0; // une donnée entière
int* pi = &i; // un pointeur sur une donnée entière
void f( int i ) // une fonction
{
…
}
void (*pf)(); // un pointeur sur une fonction
pf = f;
(*fp)();
Cours semaine 2 jour 1 Cours C++ 6
Pointeurs… (4)
 En combinant toutes ces possibilités, il
devient envisageable de définir des
pointeurs à l’intérieur même d’une classe
 Mais il est impossible de trouver l’adresse
d’une variable ou d’une fonction dans une
classe. L’opération est possible lorsque l’on
dispose d’un objet, c’est à dire de l’instance
d’une classe
Cours semaine 2 jour 1 Cours C++ 7
Pointeurs… (5)
 Il est cependant possible de prévoir
l’opération à l’aide des pointeurs vers
membres (pointer to member)
 Un member représente tant une variable qu’une
fonction
 Data member
 Member function
 De plus, une variable peut être un pointeur !
Cours semaine 2 jour 1 Cours C++ 8
Pointeurs… (6)
class Test
{
public: int i;
};
void main()
{
Test vt, *pt = &vt;
vt.i;
pt->i;
}
Cours semaine 2 jour 1 Cours C++ 9
Pointeurs… (7)
 Nous venons de définir des pointeurs sur des
variables d’instances, puisque nous en avons créé
avant les accès
 Pour créer des pointeurs vers membres, il faut
considérer la classe lors de sa définition et non pas
après son instantiation
 Dans ce cas, il faut considérer l’adresse d’une
variable dans la structure de la classe, c’est à dire
le déplacement par rapport au début du bloc
mémoire stockant la structure
Cours semaine 2 jour 1 Cours C++ 10
Pointeurs… (8)
#include <iostream>
using namespace std;
class Test {
public: int i, j, k;
void print() { cout << i << " " << j << " " << k << endl; }
};
void main () {
Test t, *pt = &t;
int Test::*pvmi = &Test::i; // def et init
pt->*pvmi = 23;
pvmi = &Test::j; // re init
pt->*pvmi = 24;
pvmi = &Test::k; // re init
pt->*pvmi = 25;
pt->print();
}
Cours semaine 2 jour 1 Cours C++ 11
Pointeurs… (9)
 Test::i permet de connaître l’importance du
déplacement à effectuer pour accèder à la position
de i dans la structure de Test
 Autrement dit, Test ne représente pas un espace de
nommage mais plutôt une prédéfinition de
l’empilement des cases mémoire telles qu’elles
seront définies dans le tas au moment d’une
instantiation
 On peut ainsi obtenir une distance depuis la position de
départ
Cours semaine 2 jour 1 Cours C++ 12
Surcharge d’opérateurs
 Nous avons vu qu’il était possible d’utiliser
plusieurs fois un même nom de méthode à
condition de changer la liste des arguments
 Surcharge de fonctions
 Il est également possible de changer la
définition d’une méthode héritée d’une
classe mère
 Polymorphisme
 Nous approfondissons demain…
Cours semaine 2 jour 1 Cours C++ 13
Surcharge d’opérateurs (2)
 En C++, il est également possible de
redéfinir les opérateurs de base au même
titre que les fonctions héritées
 Il est ainsi possible de redéfinir des opérateurs
tels que +, -
 Certains opérateurs sont en effet représentés
par ces fonctions
Cours semaine 2 jour 1 Cours C++ 14
Surcharge d’opérateurs (3)
 Différences avec les fonctions
 Les opérateurs n’utilisent pas de parenthèses pour
marquer le début et la fin de la liste des arguments
 Les arguments peuvent être soit unaires, soit binaires
 Un opérateur s’applique à un objet ou il s’applique sur deux
objets (celui à droite et celui à gauche de l’opérateur)
 Les opérateurs peuvent s’appliquer à l’objet lui-même
mais généralement ils renvoient un nouvel objet
Cours semaine 2 jour 1 Cours C++ 15
Surcharge d’opérateurs (4)
 Différences avec les fonctions (suite)
 Conséquence de l’unarité et de la
binarité, l’opérateur peut être placé
devant l’objet, entre deux objets mais
également après un objet
 In fine, la représentation syntaxique de
l’opérateur sera remplacé par un appel
de fonction, comme pour les types de
base
Cours semaine 2 jour 1 Cours C++ 16
Surcharge d’opérateurs (5)
 Très heureusement (…), il n’est pas
possible de changer le sens des opérateurs
sur les types de base
 Imaginez les problèmes dans ce cas !
 La définition de la fonction correspondant à
l’opérateur est marquée par un mot clé :
 operator
 Exemple : operator+
Cours semaine 2 jour 1 Cours C++ 17
Surcharge d’opérateurs (6)
#include <iostream>
using namespace std;
class MyInt {
public:
int i;
MyInt( int ii ) : i( ii ) {}
MyInt operator+( MyInt& v ) {
cout << "operator+" << endl;
return MyInt( i + v.i );
}
MyInt& operator+=( MyInt& v ) {
cout << "operator+=" << endl;
i += v.i;
return *this;
}
};
Cours semaine 2 jour 1 Cours C++ 18
Surcharge d’opérateurs (7)
void main()
{
cout << "opérateurs sur le type de base int" << endl;
int i = 1, j = 2, k = 3;
k += i + j;
cout << "k = " << k << endl;
cout << "opérateurs sur le type MyInt" << endl;
MyInt mii( 1 ), mij( 2 ), mik( 3 );
mik += mii + mij;
cout << "mik = " << mik.i << endl;
}
Cours semaine 2 jour 1 Cours C++ 19
Surcharge d’opérateurs (8)
 Avant de surcharger l’opérateur, il faut se
renseigner sur la véritable signature de
l’opération
 Les choses ne sont pas toujours ce qu’elles
semblent être
 Exemple : l’opérateur unaire ++ permet de
faire une incrémentation mais les résultats
dépendent de la place de l’opérateur
 Incrémentation préfixée ou postfixée
Cours semaine 2 jour 1 Cours C++ 20
Surcharge d’opérateurs (9)
…
class MyInt {
public:
int i;
…
MyInt operator++() { // pre
cout << "++MyInt" << endl;
i++;
return *this;
}
MyInt operator++( int ) { // post, notez le int
cout << "MyInt++" << endl;
MyInt preval( i );
i++; //testez aussi i += 2 !
return preval;
}
};
Cours semaine 2 jour 1 Cours C++ 21
Surcharge d’opérateurs (10)
void main()
{
…
MyInt mil = mik++;
cout << "mik++ = " << mik.i << endl;
cout << "mil = " << mil.i << endl;
MyInt min = ++mik;
cout << "++mik = " << mik.i << endl;
cout << "min = " << min.i << endl;
}
Cours semaine 2 jour 1 Cours C++ 22
Surcharge d’opérateurs (11)
 Dans le cas précédent, pour permettre de
distinguer entre l’opération ++ préfixée et
l’opération ++ postfixée, il a fallu rajouter
un argument entier
 Cet argument ne sert à rien dans le corps de la
fonction et il n’a donc pas de nom
 Il sert uniquement à distinguer les deux cas
 Le compilateur vous fera des commentaires
dans les cas douteux !
Cours semaine 2 jour 1 Cours C++ 23
Surcharge d’opérateurs (12)
 Nous venons de voir les surcharges
d’opérateurs unaires, il est également
possible de réaliser des surcharges
d’opérateurs binaires
 Les opérateurs binaires prennent en compte
l’instance courante plus l’instance d’un autre
objet
 Un exemple précédent présentait
l’operator+
Cours semaine 2 jour 1 Cours C++ 24
Surcharge d’opérateurs (13)
…
class MyInt {
…
MyInt operator+( MyInt& v )
{
cout << "operator+" << endl;
return MyInt( i + v.i );
}
…
MyInt operator-( MyInt& v )
{
cout << "operator- avec " << v.i << endl;
return MyInt( i - v.i );
}
};
Cours semaine 2 jour 1 Cours C++ 25
Surcharge d’opérateurs (14)
void main()
{
…
mil = mij + mii;
cout << "mil (mij + mii) = " << mil.i << endl;
mil = mij - mii;
cout << "mil (mij - mii) = " << mil.i << endl;
}
Cours semaine 2 jour 1 Cours C++ 26
Surcharge d’opérateurs (15)
 Un opérateur binaire particulier est
l’affectation, =, qu’il est également possible
de redéfinir !
 Bien évidemment, cette possibilité peut poser
de gros problèmes de lecture aux développeurs
non avertis
 Redéfinir l’affectation, c’est prendre de gros
risques !
Cours semaine 2 jour 1 Cours C++ 27
Surcharge d’opérateurs (16)
…
class MyInt {
…
MyInt operator=( MyInt& v )
{
if( this == &v )
{
cout << "operator= sur le même" << endl;
return *this;
}
cout << "operator= sur différents" << endl;
i = 2 * (v.i);
return *this;
}
};
Cours semaine 2 jour 1 Cours C++ 28
Surcharge d’opérateurs (17)
void main()
{
…
cout << endl << "operator+ avec mil = " << mil.i << endl << endl;
//mil = MyInt( 1 ); // décommentez après la première exécution
mil = mil;
cout << "mil (mil = mil) = " << mil.i << endl;
MyInt* pmil = &mil;
mil = *pmil;
cout << "mil (mil = *pmil) = " << mil.i << endl;
mil = mii;
cout << "mil (mil = mii) = " << mil.i << endl;
mil = mii = mik;
cout << "mil (mil = mii = mik) = " << mil.i << endl;
}
Cours semaine 2 jour 1 Cours C++ 29
Surcharge d’opérateurs (18)
void main()
{
…
// encore plus de sport avec le copy-constructor
cout << endl << "avec le copy constructor" << endl << endl;
MyInt mim = MyInt( 10 );
cout << "mim = " << mim.i << endl;
MyInt mio = mim; // X(X&)
cout << "mio = " << mio.i << endl;
mio = mim; // pas X(X&)
cout << "mio = " << mio.i << endl;
cout << endl;
}
Cours semaine 2 jour 1 Cours C++ 30
Surcharge d’opérateurs (19)
 Remarques :
 Passer les arguments en constantes dans les
fonctions associées aux opérateurs peut être une
bonne chose
 Cela évite les effets de bord
 Cela n’est pas forcément vrai pour l’affectation !
 Le type retourné n’est pas forcément celui de la
classe
 Les opérateurs logiques retournent au pire des
entiers, normalement des booléens, s’ils existent
Cours semaine 2 jour 1 Cours C++ 31
Surcharge d’opérateurs (20)
 L’opérateur d’égalité peut être défini de
manière automatique par le système pour
réaliser des conversions de type
(automatiques elles aussi)
 Il peut essayer de trouver seul un chemin pour
effectuer un appel de fonction
Cours semaine 2 jour 1 Cours C++ 32
Surcharge d’opérateurs (21)
…
class MyInt { … };
class MyOtherInt
{
public:
MyOtherInt( const MyInt& )
{}
};
void f( MyOtherInt x )
{
cout << endl << "f( MyOtherInt ) : appel" << endl << endl;
}
Cours semaine 2 jour 1 Cours C++ 33
Surcharge d’opérateurs (22)
void main()
{
…
// la fonction f n’est pas définie pour MyInt !
f( mil );
// pourtant, cela va marcher…
}
Cours semaine 2 jour 1 Cours C++ 34
Surcharge d’opérateurs (23)
 Le compilateur a trouvé un chemin, non
explicite, permettant de transformer un
MyInt en un MyOtherInt
 La fonction f a besoin d’un MyOtherInt
 Il existe un constructeur de MyOtherInt qui
prend un MyInt en argument
 Le compilateur modifie l’appel de fonction et
réalise la conversion
 Il réalise une conversion de type de même nature
que celles qui sont effectuées dans les affectations
Cours semaine 2 jour 1 Cours C++ 35
Surcharge d’opérateurs (24)
 Il est possible de restreindre ce mécanisme
et d’interdire la conversion dynamique de
type
 Le constructeur doit posséder le qualificatif
explicit
 Désormais, c’est le programmeur qui doit
assurer la conversion de type
Cours semaine 2 jour 1 Cours C++ 36
Surcharge d’opérateurs (25)
…
class MyInt { … };
class MyOtherInt
{
public:
explicit MyOtherInt( const MyInt& ) {}
};
void f( MyOtherInt x )
{
cout << endl << "f( MyOtherInt ) : appel" << endl << endl;
}
Cours semaine 2 jour 1 Cours C++ 37
Surcharge d’opérateurs (26)
void main()
{
…
f( mil ); // ne peut plus être compilé
f( MyOtherInt( mil ) ); // OK
}
Cours semaine 2 jour 1 Cours C++ 38
Surcharge d’opérateurs (27)
 Il existe cependant une autre manière de
faire :
 Il est possible de définir un opérateur de
construction d’une instance d’une classe dans
une autre classe (!)
 Un constructeur d’une classe devient ainsi une
fonction (et même un opérateur) dans une autre
classe
Cours semaine 2 jour 1 Cours C++ 39
Surcharge d’opérateurs (28)
…
class MyInt;
class MyOtherInt {
public:
explicit MyOtherInt() {}
explicit MyOtherInt( const MyInt& ){}
};
class MyInt {
…
operator MyOtherInt(){ return MyOtherInt(); }
};
void f( MyOtherInt x )
{
cout << endl << "f( MyOtherInt ) : appel" << endl << endl;
}
Cours semaine 2 jour 1 Cours C++ 40
Surcharge d’opérateurs (29)
void main()
{
…
f( mil ); // OK
f( MyOtherInt( mil ) ); // OK
}
Cours semaine 2 jour 1 Cours C++ 41
Surcharge d’opérateurs (30)
 La technique des opérateurs de construction
d’autres types a cependant des limites
 Il se peut que les chemins soient multiples
 Dans ce cas, le compilateur ne peut pas
déterminer seul lequel il doit suivre
 Il est possible d’avoir les mêmes problèmes
avec l’héritage multiple, que nous verrons
plus tard…
Cours semaine 2 jour 1 Cours C++ 42
Surcharge d’opérateurs (31)
#include <iostream>
using namespace std;
class Pomme {};
class Poire {};
class Scoubidou {
public:
operator Pomme() const;
operator Poire() const;
};
void mange( Pomme p ) { cout << "mangez des pommes" << endl; }
void mange( Poire p ) { cout << "mangez des poires" << endl; }
void main(){
Scoubidou s;
mange( s ); // ambiguous reference
}
Cours semaine 2 jour 1 Cours C++ 43
Surcharge d’opérateurs (32)
 La surcharge d’opérateurs peut s’appliquer
dans des cas encore plus exotiques que
l’affectation
 Possibilité de créer un opérateur , (virgule)
 Possibilité de redéfinir l’opérateur ->
 Très risqué aussi…
 Possibilité de redéfinir ->*
 Pour les pointeurs sur membres
 Remarque : impossible pour .* et pour .
Cours semaine 2 jour 1 Cours C++ 44
Surcharge d’opérateurs (33)
#include <iostream>
using namespace std;
class Test
{
public:
Test& operator,( Test& )
{
cout << "Test : operator," << endl;
return *this;
}
};
void main()
{
Test t1, t2;
t1, t2; // quelle lisibilité !
}
Cours semaine 2 jour 1 Cours C++ 45
Surcharge d’opérateurs (34)
 La surcharge d’opérateurs peut servir dans
certains cas
 Il ne s’agit après tout que d’une sorte de
polymorphisme
 Certains cas de surcharge d’opérateurs ont
des applications beaucoup plus pratiques
 Cela permet d’obtenir des classes dont on dirait
presque qu’elles sont d’origine !
Cours semaine 2 jour 1 Cours C++ 46
Surcharge d’opérateurs (35)
…
#include <sstream> // string streams
…
class MyInt {
…
friend ostream& operator<<( ostream& os, MyInt& v )
{
os << v.i ;
return os;
}
friend istream& operator>>( istream& is, MyInt& v )
{
is >> v.i;
return is;
}
};
Cours semaine 2 jour 1 Cours C++ 47
Surcharge d’opérateurs (36)
void main()
{
…
// jusquà présent, obligé d’accèder au data member (public)
cout << "mil = " << mil.i << endl;
// désormais, MyInt est traité normalement
// en conséquence, le data member int i peut devenir privé
cout << endl << "mil par operator<< " << mil << endl;
cin >> mil;
cout << endl << "mil par operator<< " << mil << endl;
}
Cours semaine 2 jour 1 Cours C++ 48
Surcharge d’opérateurs (37)
 La mention friend est obligatoire car
l’opérateur surchargé ne traite pas
uniquement MyInt mais également ostream
et istream
 En fait, nous définissons ici une surcharge des
opérateurs << et >> dans leurs classes
respectives
Cours semaine 2 jour 1 Cours C++ 49
Création dynamique d’objets
 Jusqu’à présent, nous avons vu différentes
manière de créer des objets à partir de la
définition d’une classe
 La manière la plus naturelle est l’appel du
constructeur
 Il est possible d’appeler le copy-constructor
 De manière indirecte, il est possible d’appeler
le constructeur de l’instance d’une classe dans
une autre classe
Cours semaine 2 jour 1 Cours C++ 50
Création dynamique d’objets (2)
 C++ héritant de C, les mécanismes de
réservation explicites de la mémoire
existent encore
 malloc (allocation) et free (libération) en C
 new et delete en C++
 New et delete sont des opérateurs en C++ et
non des fonction : il n’y a pas de
parenthèses !
 Exemple : MyInt* mii = new MyInt( 1 );
Cours semaine 2 jour 1 Cours C++ 51
Création dynamique d’objets (3)
 L’appel de new correspond en fait à l’appel
du constructeur de la classe avec les
paramètres donnés
 Comme pour le malloc de C, new renvoie
un pointeur sur la structure nouvellement
réservée et initialisée
1) réservation de la mémoire
2) construction avec les paramètres
3) retour du pointeur
Cours semaine 2 jour 1 Cours C++ 52
Création dynamique d’objets (4)
#include <iostream>
using namespace std;
class Test {
int i;
public:
Test( int v ) : i( v ) { cout << "constructeur" << endl; }
~Test() { cout << "destructeur" << endl; }
friend ostream& operator<<( ostream& os, Test* t ) {
return os << "Test avec la valeur " << t->i << endl;
}
};
void main() {
Test* t1 = new Test( 40 );
cout << t1;
delete t1;
Test t2 = Test( 20 );
cout << &t2;
}
Cours semaine 2 jour 1 Cours C++ 53
Création dynamique d’objets (5)
 La différence entre une instance définie par
valeur et une instance définie par référence
permet de voir l’application de new et
delete
 Il est également possible de définir des
tableaux d’objets par l’intermédiaire du new
 Il y a alors réservation pour un tableau d’objets
et une itération sur le constructeur pour
initialiser toute la zone mémoire
Cours semaine 2 jour 1 Cours C++ 54
Création dynamique d’objets (6)
#include <iostream>
using namespace std;
class Test {
int i;
public:
Test() : i( 0 ) { cout << "constructeur" << endl; }
Test( int v ) : i( v ) { cout << "constructeur" << endl; }
~Test() { cout << "destructeur" << endl; }
friend ostream& operator<<( ostream& os, Test* t )
{
return os << "Test avec la valeur " << t->i << endl;
}
friend ostream& operator<<( ostream& os, Test t )
{
return os << "Test avec la valeur " << t.i << endl;
}
};
Cours semaine 2 jour 1 Cours C++ 55
Création dynamique d’objets (7)
void main()
{
…
cout << "t3" << endl;
Test* t3 = new Test[ 3 ];
cout << "t3" << t3[ 1 ];
delete []t3;
cout << "t4" << endl;
Test* t4 = new Test[ 4 ];
cout << "t4[ 0 ] " << t4[ 0 ];
cout << "t4[ 3 ] " << t4[ 3 ];
cout << "t4[ 1 ] " << t4[ 1 ];
delete [ 2 ]t4; // compatibilité avec l'ancien C++
cout << "t4[ 1 ] " << t4[ 1 ]; // ne marche pas (plus ?)
cout << "t4[ 3 ] " << t4[ 3 ]; // ne marche pas non plus
}
Cours semaine 2 jour 1 Cours C++ 56
Création dynamique d’objets (8)
 Puisque new et delete sont des opérateurs, il
est possible de les surcharger
 Comme les autres…
 Les signatures standard de ces deux
opérateurs, définis au niveau global, sont :
 void* operator new( size_t sz );
 aussi : void* operator new( size_t sz, void* loc );
 void operator delete( void* m );
Cours semaine 2 jour 1 Cours C++ 57
Création dynamique d’objets (9)
…
class Test {
…
void* operator new( size_t sz ) {
cout << "new " << sz << endl;
return ::new char[ sz ];
}
void operator delete( void* p ) {
::delete []p;
}
void* operator new[]( size_t sz ) {
cout << "new[] " << sz << endl;
return ::new char[ sz ];
}
void operator delete[]( void* p ) {
::delete []p;
}
};
Cours semaine 2 jour 1 Cours C++ 58
Création dynamique d’objets (10)
void main()
{
cout << "ta" << endl;
Test* ta = new Test( 24 );
cout << "ta " << ta;
delete ta;
cout << "tb" << endl;
Test* tb = new Test[ 24 ];
cout << "tb " << tb[ 8 ];
delete []tb;
}
Cours semaine 2 jour 1 Cours C++ 59
Dynamic binding
 Lors du développement d’un système
orienté objet, il est fréquent d’avoir besoin
d’un ADT mais pas nécessairement de
connaître son implémentation
 C’est le but d’un ADT après tout…
 Un développeur peut également avoir
besoin d’un algorithme sans avoir besoin
des détails
 Pour réaliser un tri par exemple
Cours semaine 2 jour 1 Cours C++ 60
Dynamic binding (2)
 Dans les cas mentionnés, il peut être
préférable de retarder le choix d’une
implémentation le plus longtemps possible
 La décision n’est prise que lorsque qu’un
ensemble d’informations est disponible pendant
le traitement
 Dans ces cas, il peut être intéressant de
mettre en place un système d’appel
dynamique, utilisé à l’exécution et non à la
compilation
Cours semaine 2 jour 1 Cours C++ 61
Dynamic binding (3)
 Le mécanisme utilisé s’appelle le dynamic
binding (liaison dynamique)
 Ce n’est pas une création dynamique d’objet
(on parle alors de dynamic linking)
 Il s’agit d’une variante moins puissante des
pointers to members (member functions) mais
cette variante est plus compréhensible
Cours semaine 2 jour 1 Cours C++ 62
Dynamic binding (4)
 Le dynamic binding repose sur la possibilité
de tout de même appeler des fonctions
virtuelles, c’est à dire des fonctions dont on
ne possède que la signature
 Nous reviendrons sur l’héritage demain…
Cours semaine 2 jour 1 Cours C++ 63
Dynamic binding (5)
 Le dynamic binding améliore la flexibilité
et l’extensibilité
 Flexibilité : il permet de recombiner des
composants existants dans des configurations
différentes
 Extensibilité : il facilite l’intégration de
nouveaux composants dans un système existant
Cours semaine 2 jour 1 Cours C++ 64
Dynamic binding (6)
// signature de la classe mère
class Mere
{
public: virtual int vfonc( void );
};
// dans le code, on utilise un pointeur sur la classe Mere
Mere *mp = /* pointeur vers la classe fille */
mp->vfonc();
Cours semaine 2 jour 1 Cours C++ 65
Dynamic binding (7)
 La classe mère possède une fonction
virtuelle qui sera implémentée de manière
différente dans les classes filles
 Il est cependant possible de l’utiliser
 Rappelez vous de la fonction seDéplacer() sur
les Mammifères…
Cours semaine 2 jour 1 Cours C++ 66
Dynamic binding (8)
// signature de la classe fille (qui hérite de la mère)
class Fille : public Mere
{
public: int vfonc( void );
};
// pointeur sur la classe Mere contenant un pointeur
// vers une instance de la classe Fille
Fille f;
mp = &f;
mp->vfonc();
Cours semaine 2 jour 1 Cours C++ 67
Dynamic binding (9)
 Problèmes posés dans ce cas par les
mécanismes d’héritage
 Le dynamic binding peut être utilisé pour les
fonctions publiques (utilisation de l’extérieur)
 Il est possible que des fonctions appelées par la
fonction considérée soient implémentées de
manière différente dans la classe mère et la
classe fille
Cours semaine 2 jour 1 Cours C++ 68
Dynamic binding (10)
 Ces désavantages sont contournés par le
static binding
 La liaison est faite pendant la compilation
 Aucune flexibilité puisqu’aucun choix ne peut
être fait pendant l’exécution
 Cela a été fait statiquement, « syntaxiquement »
 Le static binding est aussi plus rapide : le type
de l’objet par lequel on appelle la fonction est
connu
Cours semaine 2 jour 1 Cours C++ 69
Dynamic binding (11)
 Pour le dynamic binding, il faut identifier le
type de l’objet pendant l’exécution pour
savoir où se trouve la méthode à appeler
effectivement
 L’identification de type pendant l’exécution
s’appelle le RunTime Type Identification, RTTI
 Après la RTTI, il est possible d’envoyer le bon
message à la bonne instance pour exécuter la
bonne méthode
Cours semaine 2 jour 1 Cours C++ 70
Dynamic binding (12)
 Le fait de retrouver, à partir d’un objet
général, le type spécifique de l’instance
courante et d’exécuter la bonne méthode
correspond également à du downcasting
 Pour analogie, dans un diagramme de classes
UML, pour retrouver la classe fille à partir de la
classe mère générale, il faut parcourir
l’arborescence vers le bas
Cours semaine 2 jour 1 Cours C++ 71
Dynamic binding (13)
 Le dynamic binding est un mécanisme
véritablement objet
 Même s’il est aussi facilement relié aux ADT
 Le static binding est un mécanisme
typiquement associé aux langages de
troisième génération (avec appel de
procédures et de fonctions)
Cours semaine 2 jour 1 Cours C++ 72
Questions / Remarques

Contenu connexe

Tendances

Composition, agrégation et immuabilité
Composition, agrégation et immuabilitéComposition, agrégation et immuabilité
Composition, agrégation et immuabilité
ECAM Brussels Engineering School
 
Développement informatique : Algorithmique I : Récursion et arbre
Développement informatique : Algorithmique I : Récursion et arbreDéveloppement informatique : Algorithmique I : Récursion et arbre
Développement informatique : Algorithmique I : Récursion et arbre
ECAM Brussels Engineering School
 
Python avancé : Classe et objet
Python avancé : Classe et objetPython avancé : Classe et objet
Python avancé : Classe et objet
ECAM Brussels Engineering School
 
programmation orienté objet c++
programmation orienté objet c++programmation orienté objet c++
programmation orienté objet c++
coursuniv
 
De Java à .NET
De Java à .NETDe Java à .NET
De Java à .NET
Michel Salib
 
CocoaHeads Rennes #1 : Grand Central Dispatch
CocoaHeads Rennes #1 : Grand Central DispatchCocoaHeads Rennes #1 : Grand Central Dispatch
CocoaHeads Rennes #1 : Grand Central Dispatch
CocoaHeadsRNS
 
Chapitre 2 poo classe objet c++
Chapitre 2 poo classe objet c++Chapitre 2 poo classe objet c++
Chapitre 2 poo classe objet c++
Amel Morchdi
 
Java uik-chap4-poo3
Java uik-chap4-poo3Java uik-chap4-poo3
Java uik-chap4-poo3
Amel Morchdi
 
Python avancé : Interface graphique et programmation évènementielle
Python avancé : Interface graphique et programmation évènementiellePython avancé : Interface graphique et programmation évènementielle
Python avancé : Interface graphique et programmation évènementielle
ECAM Brussels Engineering School
 
Polymorphisme, interface et classe abstraite
Polymorphisme, interface et classe abstraitePolymorphisme, interface et classe abstraite
Polymorphisme, interface et classe abstraite
ECAM Brussels Engineering School
 
Memo java
Memo javaMemo java
Memo java
Ghazouani Mahdi
 
Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...
ECAM Brussels Engineering School
 
Développement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulièresDéveloppement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulières
ECAM Brussels Engineering School
 
Cours c++
Cours c++Cours c++
Cours c++
Nahla BelHaj
 
Python avancé : Ensemble, dictionnaire et base de données
Python avancé : Ensemble, dictionnaire et base de donnéesPython avancé : Ensemble, dictionnaire et base de données
Python avancé : Ensemble, dictionnaire et base de données
ECAM Brussels Engineering School
 
Chapitre6: Surcharge des opérateurs
Chapitre6:  Surcharge des opérateursChapitre6:  Surcharge des opérateurs
Chapitre6: Surcharge des opérateurs
Aziz Darouichi
 
Chapitre5: Classes et objets
Chapitre5: Classes et objetsChapitre5: Classes et objets
Chapitre5: Classes et objets
Aziz Darouichi
 
Héritage et redéfinition de méthode
Héritage et redéfinition de méthodeHéritage et redéfinition de méthode
Héritage et redéfinition de méthode
ECAM Brussels Engineering School
 
Corrige tp java
Corrige tp javaCorrige tp java
Corrige tp java
Maya Medjdoub
 
Type abstrait de données
Type abstrait de donnéesType abstrait de données
Type abstrait de données
ECAM Brussels Engineering School
 

Tendances (20)

Composition, agrégation et immuabilité
Composition, agrégation et immuabilitéComposition, agrégation et immuabilité
Composition, agrégation et immuabilité
 
Développement informatique : Algorithmique I : Récursion et arbre
Développement informatique : Algorithmique I : Récursion et arbreDéveloppement informatique : Algorithmique I : Récursion et arbre
Développement informatique : Algorithmique I : Récursion et arbre
 
Python avancé : Classe et objet
Python avancé : Classe et objetPython avancé : Classe et objet
Python avancé : Classe et objet
 
programmation orienté objet c++
programmation orienté objet c++programmation orienté objet c++
programmation orienté objet c++
 
De Java à .NET
De Java à .NETDe Java à .NET
De Java à .NET
 
CocoaHeads Rennes #1 : Grand Central Dispatch
CocoaHeads Rennes #1 : Grand Central DispatchCocoaHeads Rennes #1 : Grand Central Dispatch
CocoaHeads Rennes #1 : Grand Central Dispatch
 
Chapitre 2 poo classe objet c++
Chapitre 2 poo classe objet c++Chapitre 2 poo classe objet c++
Chapitre 2 poo classe objet c++
 
Java uik-chap4-poo3
Java uik-chap4-poo3Java uik-chap4-poo3
Java uik-chap4-poo3
 
Python avancé : Interface graphique et programmation évènementielle
Python avancé : Interface graphique et programmation évènementiellePython avancé : Interface graphique et programmation évènementielle
Python avancé : Interface graphique et programmation évènementielle
 
Polymorphisme, interface et classe abstraite
Polymorphisme, interface et classe abstraitePolymorphisme, interface et classe abstraite
Polymorphisme, interface et classe abstraite
 
Memo java
Memo javaMemo java
Memo java
 
Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...
 
Développement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulièresDéveloppement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulières
 
Cours c++
Cours c++Cours c++
Cours c++
 
Python avancé : Ensemble, dictionnaire et base de données
Python avancé : Ensemble, dictionnaire et base de donnéesPython avancé : Ensemble, dictionnaire et base de données
Python avancé : Ensemble, dictionnaire et base de données
 
Chapitre6: Surcharge des opérateurs
Chapitre6:  Surcharge des opérateursChapitre6:  Surcharge des opérateurs
Chapitre6: Surcharge des opérateurs
 
Chapitre5: Classes et objets
Chapitre5: Classes et objetsChapitre5: Classes et objets
Chapitre5: Classes et objets
 
Héritage et redéfinition de méthode
Héritage et redéfinition de méthodeHéritage et redéfinition de méthode
Héritage et redéfinition de méthode
 
Corrige tp java
Corrige tp javaCorrige tp java
Corrige tp java
 
Type abstrait de données
Type abstrait de donnéesType abstrait de données
Type abstrait de données
 

Similaire à Cours de C++, en français, 2002 - Cours 2.1

System c eniso_jan_fev_07
System c eniso_jan_fev_07System c eniso_jan_fev_07
System c eniso_jan_fev_07
haythem_2015
 
Cours de C++ / Tronc commun deuxième année ISIMA
Cours de C++ / Tronc commun deuxième année ISIMACours de C++ / Tronc commun deuxième année ISIMA
Cours de C++ / Tronc commun deuxième année ISIMA
Loic Yon
 
Cours de C++, en français, 2002 - Cours 1.5
Cours de C++, en français, 2002 - Cours 1.5Cours de C++, en français, 2002 - Cours 1.5
Cours de C++, en français, 2002 - Cours 1.5
Laurent BUNIET
 
Scala : programmation fonctionnelle
Scala : programmation fonctionnelleScala : programmation fonctionnelle
Scala : programmation fonctionnelle
MICHRAFY MUSTAFA
 
02 Spécificité du C++ COURS SYS SYSSSSSS
02 Spécificité du C++  COURS SYS SYSSSSSS02 Spécificité du C++  COURS SYS SYSSSSSS
02 Spécificité du C++ COURS SYS SYSSSSSS
AyoubElmrabet6
 
Chapitre 04 : les fonctions
Chapitre 04 : les fonctionsChapitre 04 : les fonctions
Chapitre 04 : les fonctions
L’Université Hassan 1er Settat
 
201303 - Java8
201303 - Java8201303 - Java8
201303 - Java8
lyonjug
 
Patron observer
Patron observerPatron observer
Patron observer
Hibatallah Aouadni
 
TP2 Atelier C++/ GL2 INSAT / Tunisie
TP2 Atelier C++/ GL2 INSAT / TunisieTP2 Atelier C++/ GL2 INSAT / Tunisie
TP2 Atelier C++/ GL2 INSAT / Tunisie
Mariem ZAOUALI
 
POO-chapitre3.pptx
POO-chapitre3.pptxPOO-chapitre3.pptx
POO-chapitre3.pptx
ImaneLoukili7
 
Deuxième partie.pptx
Deuxième partie.pptxDeuxième partie.pptx
Deuxième partie.pptx
SafaeLhr1
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logicielle
cyrilgandon
 
Formation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objetFormation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objet
kemenaran
 
Memojava 100604104941-phpapp02
Memojava 100604104941-phpapp02Memojava 100604104941-phpapp02
Memojava 100604104941-phpapp02
Rahma Boufalgha
 
C# 7 - Nouveautés
C# 7 - NouveautésC# 7 - Nouveautés
C# 7 - Nouveautés
James RAVAILLE
 
POO en C++: Les fonctions
POO en C++: Les fonctionsPOO en C++: Les fonctions
POO en C++: Les fonctions
Amina HAMEURLAINE
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScript
Kristen Le Liboux
 
Cours de C++, en français, 2002 - Cours 2.4
Cours de C++, en français, 2002 - Cours 2.4Cours de C++, en français, 2002 - Cours 2.4
Cours de C++, en français, 2002 - Cours 2.4
Laurent BUNIET
 
Cours de C++, en français, 2002 - Cours 3.5
Cours de C++, en français, 2002 - Cours 3.5Cours de C++, en français, 2002 - Cours 3.5
Cours de C++, en français, 2002 - Cours 3.5
Laurent BUNIET
 

Similaire à Cours de C++, en français, 2002 - Cours 2.1 (20)

System c eniso_jan_fev_07
System c eniso_jan_fev_07System c eniso_jan_fev_07
System c eniso_jan_fev_07
 
Cours de C++ / Tronc commun deuxième année ISIMA
Cours de C++ / Tronc commun deuxième année ISIMACours de C++ / Tronc commun deuxième année ISIMA
Cours de C++ / Tronc commun deuxième année ISIMA
 
Cours de C++, en français, 2002 - Cours 1.5
Cours de C++, en français, 2002 - Cours 1.5Cours de C++, en français, 2002 - Cours 1.5
Cours de C++, en français, 2002 - Cours 1.5
 
Scala : programmation fonctionnelle
Scala : programmation fonctionnelleScala : programmation fonctionnelle
Scala : programmation fonctionnelle
 
02 Spécificité du C++ COURS SYS SYSSSSSS
02 Spécificité du C++  COURS SYS SYSSSSSS02 Spécificité du C++  COURS SYS SYSSSSSS
02 Spécificité du C++ COURS SYS SYSSSSSS
 
Chapitre 04 : les fonctions
Chapitre 04 : les fonctionsChapitre 04 : les fonctions
Chapitre 04 : les fonctions
 
201303 - Java8
201303 - Java8201303 - Java8
201303 - Java8
 
Patron observer
Patron observerPatron observer
Patron observer
 
TP2 Atelier C++/ GL2 INSAT / Tunisie
TP2 Atelier C++/ GL2 INSAT / TunisieTP2 Atelier C++/ GL2 INSAT / Tunisie
TP2 Atelier C++/ GL2 INSAT / Tunisie
 
POO-chapitre3.pptx
POO-chapitre3.pptxPOO-chapitre3.pptx
POO-chapitre3.pptx
 
Deuxième partie.pptx
Deuxième partie.pptxDeuxième partie.pptx
Deuxième partie.pptx
 
Qualité logicielle
Qualité logicielleQualité logicielle
Qualité logicielle
 
Formation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objetFormation C# - Cours 3 - Programmation objet
Formation C# - Cours 3 - Programmation objet
 
Memojava 100604104941-phpapp02
Memojava 100604104941-phpapp02Memojava 100604104941-phpapp02
Memojava 100604104941-phpapp02
 
C# 7 - Nouveautés
C# 7 - NouveautésC# 7 - Nouveautés
C# 7 - Nouveautés
 
POO en C++: Les fonctions
POO en C++: Les fonctionsPOO en C++: Les fonctions
POO en C++: Les fonctions
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScript
 
Cours de C++, en français, 2002 - Cours 2.4
Cours de C++, en français, 2002 - Cours 2.4Cours de C++, en français, 2002 - Cours 2.4
Cours de C++, en français, 2002 - Cours 2.4
 
Cours de C++, en français, 2002 - Cours 3.5
Cours de C++, en français, 2002 - Cours 3.5Cours de C++, en français, 2002 - Cours 3.5
Cours de C++, en français, 2002 - Cours 3.5
 
Part1
Part1Part1
Part1
 

Plus de Laurent BUNIET

Cours de C++, en français, 2002 - Cours 3.4
Cours de C++, en français, 2002 - Cours 3.4Cours de C++, en français, 2002 - Cours 3.4
Cours de C++, en français, 2002 - Cours 3.4
Laurent BUNIET
 
Cours de C++, en français, 2002 - Cours 3.3
Cours de C++, en français, 2002 - Cours 3.3Cours de C++, en français, 2002 - Cours 3.3
Cours de C++, en français, 2002 - Cours 3.3
Laurent BUNIET
 
Cours de C++, en français, 2002 - Cours 3.2
Cours de C++, en français, 2002 - Cours 3.2Cours de C++, en français, 2002 - Cours 3.2
Cours de C++, en français, 2002 - Cours 3.2
Laurent BUNIET
 
Cours de C++, en français, 2002 - Cours 3.1
Cours de C++, en français, 2002 - Cours 3.1Cours de C++, en français, 2002 - Cours 3.1
Cours de C++, en français, 2002 - Cours 3.1
Laurent BUNIET
 
Cours de C++, en français, 2002 - Cours 2.5
Cours de C++, en français, 2002 - Cours 2.5Cours de C++, en français, 2002 - Cours 2.5
Cours de C++, en français, 2002 - Cours 2.5
Laurent BUNIET
 
Cours de C++, en français, 2002 - Cours 2.3
Cours de C++, en français, 2002 - Cours 2.3Cours de C++, en français, 2002 - Cours 2.3
Cours de C++, en français, 2002 - Cours 2.3
Laurent BUNIET
 
Cours de C++, en français, 2002 - Cours 2.2
Cours de C++, en français, 2002 - Cours 2.2Cours de C++, en français, 2002 - Cours 2.2
Cours de C++, en français, 2002 - Cours 2.2
Laurent BUNIET
 
Cours de C++, en français, 2002 - Cours 1.4
Cours de C++, en français, 2002 - Cours 1.4Cours de C++, en français, 2002 - Cours 1.4
Cours de C++, en français, 2002 - Cours 1.4
Laurent BUNIET
 
Cours de C++, en français, 2002 - Cours 1.3
Cours de C++, en français, 2002 - Cours 1.3Cours de C++, en français, 2002 - Cours 1.3
Cours de C++, en français, 2002 - Cours 1.3
Laurent BUNIET
 
Cours de C++, en français, 2002 - Cours 1.2
Cours de C++, en français, 2002 - Cours 1.2Cours de C++, en français, 2002 - Cours 1.2
Cours de C++, en français, 2002 - Cours 1.2
Laurent BUNIET
 
Cours de C++, en français, 2002 - Cours 1.1
Cours de C++, en français, 2002 - Cours 1.1Cours de C++, en français, 2002 - Cours 1.1
Cours de C++, en français, 2002 - Cours 1.1
Laurent BUNIET
 
Cours de C++, en français, 2002 - Plan
Cours de C++, en français, 2002 - PlanCours de C++, en français, 2002 - Plan
Cours de C++, en français, 2002 - Plan
Laurent BUNIET
 

Plus de Laurent BUNIET (12)

Cours de C++, en français, 2002 - Cours 3.4
Cours de C++, en français, 2002 - Cours 3.4Cours de C++, en français, 2002 - Cours 3.4
Cours de C++, en français, 2002 - Cours 3.4
 
Cours de C++, en français, 2002 - Cours 3.3
Cours de C++, en français, 2002 - Cours 3.3Cours de C++, en français, 2002 - Cours 3.3
Cours de C++, en français, 2002 - Cours 3.3
 
Cours de C++, en français, 2002 - Cours 3.2
Cours de C++, en français, 2002 - Cours 3.2Cours de C++, en français, 2002 - Cours 3.2
Cours de C++, en français, 2002 - Cours 3.2
 
Cours de C++, en français, 2002 - Cours 3.1
Cours de C++, en français, 2002 - Cours 3.1Cours de C++, en français, 2002 - Cours 3.1
Cours de C++, en français, 2002 - Cours 3.1
 
Cours de C++, en français, 2002 - Cours 2.5
Cours de C++, en français, 2002 - Cours 2.5Cours de C++, en français, 2002 - Cours 2.5
Cours de C++, en français, 2002 - Cours 2.5
 
Cours de C++, en français, 2002 - Cours 2.3
Cours de C++, en français, 2002 - Cours 2.3Cours de C++, en français, 2002 - Cours 2.3
Cours de C++, en français, 2002 - Cours 2.3
 
Cours de C++, en français, 2002 - Cours 2.2
Cours de C++, en français, 2002 - Cours 2.2Cours de C++, en français, 2002 - Cours 2.2
Cours de C++, en français, 2002 - Cours 2.2
 
Cours de C++, en français, 2002 - Cours 1.4
Cours de C++, en français, 2002 - Cours 1.4Cours de C++, en français, 2002 - Cours 1.4
Cours de C++, en français, 2002 - Cours 1.4
 
Cours de C++, en français, 2002 - Cours 1.3
Cours de C++, en français, 2002 - Cours 1.3Cours de C++, en français, 2002 - Cours 1.3
Cours de C++, en français, 2002 - Cours 1.3
 
Cours de C++, en français, 2002 - Cours 1.2
Cours de C++, en français, 2002 - Cours 1.2Cours de C++, en français, 2002 - Cours 1.2
Cours de C++, en français, 2002 - Cours 1.2
 
Cours de C++, en français, 2002 - Cours 1.1
Cours de C++, en français, 2002 - Cours 1.1Cours de C++, en français, 2002 - Cours 1.1
Cours de C++, en français, 2002 - Cours 1.1
 
Cours de C++, en français, 2002 - Plan
Cours de C++, en français, 2002 - PlanCours de C++, en français, 2002 - Plan
Cours de C++, en français, 2002 - Plan
 

Cours de C++, en français, 2002 - Cours 2.1

  • 2. Plan du jour  Pointeurs, références et copies d’objets : la suite  Pointer to members  Surcharge d’opérateur  Création dynamique d’objets  Dynamic binding  RTTI Cours semaine 2 jour 1 Cours C++ 2
  • 3. Cours semaine 2 jour 1 Cours C++ 3 Pointeurs…  Dans le cours précédent, nous avons parlé :  Des pointeurs, un type de base en C et C++ !  Des passages par références (avec les pointeurs) et des passage par valeurs (avec des copies des valeurs)  Des copies d’objets pour que ceux-ci puissent être passés par valeur (copy-contructor)  C++ offre encore une possibilité de travailler avec les pointeurs dans les classes
  • 4. Cours semaine 2 jour 1 Cours C++ 4 Pointeurs… (2)  Un classe est une structure qui définit un ensemble :  de variables, généralement privées,  De méthodes ou de signatures de méthodes, qui peuvent être publiques, protégées ou privées  Un pointeur permet de désigner des variables, il permet également de désigner des fonctions
  • 5. Cours semaine 2 jour 1 Cours C++ 5 Pointeurs… (3) int i = 0; // une donnée entière int* pi = &i; // un pointeur sur une donnée entière void f( int i ) // une fonction { … } void (*pf)(); // un pointeur sur une fonction pf = f; (*fp)();
  • 6. Cours semaine 2 jour 1 Cours C++ 6 Pointeurs… (4)  En combinant toutes ces possibilités, il devient envisageable de définir des pointeurs à l’intérieur même d’une classe  Mais il est impossible de trouver l’adresse d’une variable ou d’une fonction dans une classe. L’opération est possible lorsque l’on dispose d’un objet, c’est à dire de l’instance d’une classe
  • 7. Cours semaine 2 jour 1 Cours C++ 7 Pointeurs… (5)  Il est cependant possible de prévoir l’opération à l’aide des pointeurs vers membres (pointer to member)  Un member représente tant une variable qu’une fonction  Data member  Member function  De plus, une variable peut être un pointeur !
  • 8. Cours semaine 2 jour 1 Cours C++ 8 Pointeurs… (6) class Test { public: int i; }; void main() { Test vt, *pt = &vt; vt.i; pt->i; }
  • 9. Cours semaine 2 jour 1 Cours C++ 9 Pointeurs… (7)  Nous venons de définir des pointeurs sur des variables d’instances, puisque nous en avons créé avant les accès  Pour créer des pointeurs vers membres, il faut considérer la classe lors de sa définition et non pas après son instantiation  Dans ce cas, il faut considérer l’adresse d’une variable dans la structure de la classe, c’est à dire le déplacement par rapport au début du bloc mémoire stockant la structure
  • 10. Cours semaine 2 jour 1 Cours C++ 10 Pointeurs… (8) #include <iostream> using namespace std; class Test { public: int i, j, k; void print() { cout << i << " " << j << " " << k << endl; } }; void main () { Test t, *pt = &t; int Test::*pvmi = &Test::i; // def et init pt->*pvmi = 23; pvmi = &Test::j; // re init pt->*pvmi = 24; pvmi = &Test::k; // re init pt->*pvmi = 25; pt->print(); }
  • 11. Cours semaine 2 jour 1 Cours C++ 11 Pointeurs… (9)  Test::i permet de connaître l’importance du déplacement à effectuer pour accèder à la position de i dans la structure de Test  Autrement dit, Test ne représente pas un espace de nommage mais plutôt une prédéfinition de l’empilement des cases mémoire telles qu’elles seront définies dans le tas au moment d’une instantiation  On peut ainsi obtenir une distance depuis la position de départ
  • 12. Cours semaine 2 jour 1 Cours C++ 12 Surcharge d’opérateurs  Nous avons vu qu’il était possible d’utiliser plusieurs fois un même nom de méthode à condition de changer la liste des arguments  Surcharge de fonctions  Il est également possible de changer la définition d’une méthode héritée d’une classe mère  Polymorphisme  Nous approfondissons demain…
  • 13. Cours semaine 2 jour 1 Cours C++ 13 Surcharge d’opérateurs (2)  En C++, il est également possible de redéfinir les opérateurs de base au même titre que les fonctions héritées  Il est ainsi possible de redéfinir des opérateurs tels que +, -  Certains opérateurs sont en effet représentés par ces fonctions
  • 14. Cours semaine 2 jour 1 Cours C++ 14 Surcharge d’opérateurs (3)  Différences avec les fonctions  Les opérateurs n’utilisent pas de parenthèses pour marquer le début et la fin de la liste des arguments  Les arguments peuvent être soit unaires, soit binaires  Un opérateur s’applique à un objet ou il s’applique sur deux objets (celui à droite et celui à gauche de l’opérateur)  Les opérateurs peuvent s’appliquer à l’objet lui-même mais généralement ils renvoient un nouvel objet
  • 15. Cours semaine 2 jour 1 Cours C++ 15 Surcharge d’opérateurs (4)  Différences avec les fonctions (suite)  Conséquence de l’unarité et de la binarité, l’opérateur peut être placé devant l’objet, entre deux objets mais également après un objet  In fine, la représentation syntaxique de l’opérateur sera remplacé par un appel de fonction, comme pour les types de base
  • 16. Cours semaine 2 jour 1 Cours C++ 16 Surcharge d’opérateurs (5)  Très heureusement (…), il n’est pas possible de changer le sens des opérateurs sur les types de base  Imaginez les problèmes dans ce cas !  La définition de la fonction correspondant à l’opérateur est marquée par un mot clé :  operator  Exemple : operator+
  • 17. Cours semaine 2 jour 1 Cours C++ 17 Surcharge d’opérateurs (6) #include <iostream> using namespace std; class MyInt { public: int i; MyInt( int ii ) : i( ii ) {} MyInt operator+( MyInt& v ) { cout << "operator+" << endl; return MyInt( i + v.i ); } MyInt& operator+=( MyInt& v ) { cout << "operator+=" << endl; i += v.i; return *this; } };
  • 18. Cours semaine 2 jour 1 Cours C++ 18 Surcharge d’opérateurs (7) void main() { cout << "opérateurs sur le type de base int" << endl; int i = 1, j = 2, k = 3; k += i + j; cout << "k = " << k << endl; cout << "opérateurs sur le type MyInt" << endl; MyInt mii( 1 ), mij( 2 ), mik( 3 ); mik += mii + mij; cout << "mik = " << mik.i << endl; }
  • 19. Cours semaine 2 jour 1 Cours C++ 19 Surcharge d’opérateurs (8)  Avant de surcharger l’opérateur, il faut se renseigner sur la véritable signature de l’opération  Les choses ne sont pas toujours ce qu’elles semblent être  Exemple : l’opérateur unaire ++ permet de faire une incrémentation mais les résultats dépendent de la place de l’opérateur  Incrémentation préfixée ou postfixée
  • 20. Cours semaine 2 jour 1 Cours C++ 20 Surcharge d’opérateurs (9) … class MyInt { public: int i; … MyInt operator++() { // pre cout << "++MyInt" << endl; i++; return *this; } MyInt operator++( int ) { // post, notez le int cout << "MyInt++" << endl; MyInt preval( i ); i++; //testez aussi i += 2 ! return preval; } };
  • 21. Cours semaine 2 jour 1 Cours C++ 21 Surcharge d’opérateurs (10) void main() { … MyInt mil = mik++; cout << "mik++ = " << mik.i << endl; cout << "mil = " << mil.i << endl; MyInt min = ++mik; cout << "++mik = " << mik.i << endl; cout << "min = " << min.i << endl; }
  • 22. Cours semaine 2 jour 1 Cours C++ 22 Surcharge d’opérateurs (11)  Dans le cas précédent, pour permettre de distinguer entre l’opération ++ préfixée et l’opération ++ postfixée, il a fallu rajouter un argument entier  Cet argument ne sert à rien dans le corps de la fonction et il n’a donc pas de nom  Il sert uniquement à distinguer les deux cas  Le compilateur vous fera des commentaires dans les cas douteux !
  • 23. Cours semaine 2 jour 1 Cours C++ 23 Surcharge d’opérateurs (12)  Nous venons de voir les surcharges d’opérateurs unaires, il est également possible de réaliser des surcharges d’opérateurs binaires  Les opérateurs binaires prennent en compte l’instance courante plus l’instance d’un autre objet  Un exemple précédent présentait l’operator+
  • 24. Cours semaine 2 jour 1 Cours C++ 24 Surcharge d’opérateurs (13) … class MyInt { … MyInt operator+( MyInt& v ) { cout << "operator+" << endl; return MyInt( i + v.i ); } … MyInt operator-( MyInt& v ) { cout << "operator- avec " << v.i << endl; return MyInt( i - v.i ); } };
  • 25. Cours semaine 2 jour 1 Cours C++ 25 Surcharge d’opérateurs (14) void main() { … mil = mij + mii; cout << "mil (mij + mii) = " << mil.i << endl; mil = mij - mii; cout << "mil (mij - mii) = " << mil.i << endl; }
  • 26. Cours semaine 2 jour 1 Cours C++ 26 Surcharge d’opérateurs (15)  Un opérateur binaire particulier est l’affectation, =, qu’il est également possible de redéfinir !  Bien évidemment, cette possibilité peut poser de gros problèmes de lecture aux développeurs non avertis  Redéfinir l’affectation, c’est prendre de gros risques !
  • 27. Cours semaine 2 jour 1 Cours C++ 27 Surcharge d’opérateurs (16) … class MyInt { … MyInt operator=( MyInt& v ) { if( this == &v ) { cout << "operator= sur le même" << endl; return *this; } cout << "operator= sur différents" << endl; i = 2 * (v.i); return *this; } };
  • 28. Cours semaine 2 jour 1 Cours C++ 28 Surcharge d’opérateurs (17) void main() { … cout << endl << "operator+ avec mil = " << mil.i << endl << endl; //mil = MyInt( 1 ); // décommentez après la première exécution mil = mil; cout << "mil (mil = mil) = " << mil.i << endl; MyInt* pmil = &mil; mil = *pmil; cout << "mil (mil = *pmil) = " << mil.i << endl; mil = mii; cout << "mil (mil = mii) = " << mil.i << endl; mil = mii = mik; cout << "mil (mil = mii = mik) = " << mil.i << endl; }
  • 29. Cours semaine 2 jour 1 Cours C++ 29 Surcharge d’opérateurs (18) void main() { … // encore plus de sport avec le copy-constructor cout << endl << "avec le copy constructor" << endl << endl; MyInt mim = MyInt( 10 ); cout << "mim = " << mim.i << endl; MyInt mio = mim; // X(X&) cout << "mio = " << mio.i << endl; mio = mim; // pas X(X&) cout << "mio = " << mio.i << endl; cout << endl; }
  • 30. Cours semaine 2 jour 1 Cours C++ 30 Surcharge d’opérateurs (19)  Remarques :  Passer les arguments en constantes dans les fonctions associées aux opérateurs peut être une bonne chose  Cela évite les effets de bord  Cela n’est pas forcément vrai pour l’affectation !  Le type retourné n’est pas forcément celui de la classe  Les opérateurs logiques retournent au pire des entiers, normalement des booléens, s’ils existent
  • 31. Cours semaine 2 jour 1 Cours C++ 31 Surcharge d’opérateurs (20)  L’opérateur d’égalité peut être défini de manière automatique par le système pour réaliser des conversions de type (automatiques elles aussi)  Il peut essayer de trouver seul un chemin pour effectuer un appel de fonction
  • 32. Cours semaine 2 jour 1 Cours C++ 32 Surcharge d’opérateurs (21) … class MyInt { … }; class MyOtherInt { public: MyOtherInt( const MyInt& ) {} }; void f( MyOtherInt x ) { cout << endl << "f( MyOtherInt ) : appel" << endl << endl; }
  • 33. Cours semaine 2 jour 1 Cours C++ 33 Surcharge d’opérateurs (22) void main() { … // la fonction f n’est pas définie pour MyInt ! f( mil ); // pourtant, cela va marcher… }
  • 34. Cours semaine 2 jour 1 Cours C++ 34 Surcharge d’opérateurs (23)  Le compilateur a trouvé un chemin, non explicite, permettant de transformer un MyInt en un MyOtherInt  La fonction f a besoin d’un MyOtherInt  Il existe un constructeur de MyOtherInt qui prend un MyInt en argument  Le compilateur modifie l’appel de fonction et réalise la conversion  Il réalise une conversion de type de même nature que celles qui sont effectuées dans les affectations
  • 35. Cours semaine 2 jour 1 Cours C++ 35 Surcharge d’opérateurs (24)  Il est possible de restreindre ce mécanisme et d’interdire la conversion dynamique de type  Le constructeur doit posséder le qualificatif explicit  Désormais, c’est le programmeur qui doit assurer la conversion de type
  • 36. Cours semaine 2 jour 1 Cours C++ 36 Surcharge d’opérateurs (25) … class MyInt { … }; class MyOtherInt { public: explicit MyOtherInt( const MyInt& ) {} }; void f( MyOtherInt x ) { cout << endl << "f( MyOtherInt ) : appel" << endl << endl; }
  • 37. Cours semaine 2 jour 1 Cours C++ 37 Surcharge d’opérateurs (26) void main() { … f( mil ); // ne peut plus être compilé f( MyOtherInt( mil ) ); // OK }
  • 38. Cours semaine 2 jour 1 Cours C++ 38 Surcharge d’opérateurs (27)  Il existe cependant une autre manière de faire :  Il est possible de définir un opérateur de construction d’une instance d’une classe dans une autre classe (!)  Un constructeur d’une classe devient ainsi une fonction (et même un opérateur) dans une autre classe
  • 39. Cours semaine 2 jour 1 Cours C++ 39 Surcharge d’opérateurs (28) … class MyInt; class MyOtherInt { public: explicit MyOtherInt() {} explicit MyOtherInt( const MyInt& ){} }; class MyInt { … operator MyOtherInt(){ return MyOtherInt(); } }; void f( MyOtherInt x ) { cout << endl << "f( MyOtherInt ) : appel" << endl << endl; }
  • 40. Cours semaine 2 jour 1 Cours C++ 40 Surcharge d’opérateurs (29) void main() { … f( mil ); // OK f( MyOtherInt( mil ) ); // OK }
  • 41. Cours semaine 2 jour 1 Cours C++ 41 Surcharge d’opérateurs (30)  La technique des opérateurs de construction d’autres types a cependant des limites  Il se peut que les chemins soient multiples  Dans ce cas, le compilateur ne peut pas déterminer seul lequel il doit suivre  Il est possible d’avoir les mêmes problèmes avec l’héritage multiple, que nous verrons plus tard…
  • 42. Cours semaine 2 jour 1 Cours C++ 42 Surcharge d’opérateurs (31) #include <iostream> using namespace std; class Pomme {}; class Poire {}; class Scoubidou { public: operator Pomme() const; operator Poire() const; }; void mange( Pomme p ) { cout << "mangez des pommes" << endl; } void mange( Poire p ) { cout << "mangez des poires" << endl; } void main(){ Scoubidou s; mange( s ); // ambiguous reference }
  • 43. Cours semaine 2 jour 1 Cours C++ 43 Surcharge d’opérateurs (32)  La surcharge d’opérateurs peut s’appliquer dans des cas encore plus exotiques que l’affectation  Possibilité de créer un opérateur , (virgule)  Possibilité de redéfinir l’opérateur ->  Très risqué aussi…  Possibilité de redéfinir ->*  Pour les pointeurs sur membres  Remarque : impossible pour .* et pour .
  • 44. Cours semaine 2 jour 1 Cours C++ 44 Surcharge d’opérateurs (33) #include <iostream> using namespace std; class Test { public: Test& operator,( Test& ) { cout << "Test : operator," << endl; return *this; } }; void main() { Test t1, t2; t1, t2; // quelle lisibilité ! }
  • 45. Cours semaine 2 jour 1 Cours C++ 45 Surcharge d’opérateurs (34)  La surcharge d’opérateurs peut servir dans certains cas  Il ne s’agit après tout que d’une sorte de polymorphisme  Certains cas de surcharge d’opérateurs ont des applications beaucoup plus pratiques  Cela permet d’obtenir des classes dont on dirait presque qu’elles sont d’origine !
  • 46. Cours semaine 2 jour 1 Cours C++ 46 Surcharge d’opérateurs (35) … #include <sstream> // string streams … class MyInt { … friend ostream& operator<<( ostream& os, MyInt& v ) { os << v.i ; return os; } friend istream& operator>>( istream& is, MyInt& v ) { is >> v.i; return is; } };
  • 47. Cours semaine 2 jour 1 Cours C++ 47 Surcharge d’opérateurs (36) void main() { … // jusquà présent, obligé d’accèder au data member (public) cout << "mil = " << mil.i << endl; // désormais, MyInt est traité normalement // en conséquence, le data member int i peut devenir privé cout << endl << "mil par operator<< " << mil << endl; cin >> mil; cout << endl << "mil par operator<< " << mil << endl; }
  • 48. Cours semaine 2 jour 1 Cours C++ 48 Surcharge d’opérateurs (37)  La mention friend est obligatoire car l’opérateur surchargé ne traite pas uniquement MyInt mais également ostream et istream  En fait, nous définissons ici une surcharge des opérateurs << et >> dans leurs classes respectives
  • 49. Cours semaine 2 jour 1 Cours C++ 49 Création dynamique d’objets  Jusqu’à présent, nous avons vu différentes manière de créer des objets à partir de la définition d’une classe  La manière la plus naturelle est l’appel du constructeur  Il est possible d’appeler le copy-constructor  De manière indirecte, il est possible d’appeler le constructeur de l’instance d’une classe dans une autre classe
  • 50. Cours semaine 2 jour 1 Cours C++ 50 Création dynamique d’objets (2)  C++ héritant de C, les mécanismes de réservation explicites de la mémoire existent encore  malloc (allocation) et free (libération) en C  new et delete en C++  New et delete sont des opérateurs en C++ et non des fonction : il n’y a pas de parenthèses !  Exemple : MyInt* mii = new MyInt( 1 );
  • 51. Cours semaine 2 jour 1 Cours C++ 51 Création dynamique d’objets (3)  L’appel de new correspond en fait à l’appel du constructeur de la classe avec les paramètres donnés  Comme pour le malloc de C, new renvoie un pointeur sur la structure nouvellement réservée et initialisée 1) réservation de la mémoire 2) construction avec les paramètres 3) retour du pointeur
  • 52. Cours semaine 2 jour 1 Cours C++ 52 Création dynamique d’objets (4) #include <iostream> using namespace std; class Test { int i; public: Test( int v ) : i( v ) { cout << "constructeur" << endl; } ~Test() { cout << "destructeur" << endl; } friend ostream& operator<<( ostream& os, Test* t ) { return os << "Test avec la valeur " << t->i << endl; } }; void main() { Test* t1 = new Test( 40 ); cout << t1; delete t1; Test t2 = Test( 20 ); cout << &t2; }
  • 53. Cours semaine 2 jour 1 Cours C++ 53 Création dynamique d’objets (5)  La différence entre une instance définie par valeur et une instance définie par référence permet de voir l’application de new et delete  Il est également possible de définir des tableaux d’objets par l’intermédiaire du new  Il y a alors réservation pour un tableau d’objets et une itération sur le constructeur pour initialiser toute la zone mémoire
  • 54. Cours semaine 2 jour 1 Cours C++ 54 Création dynamique d’objets (6) #include <iostream> using namespace std; class Test { int i; public: Test() : i( 0 ) { cout << "constructeur" << endl; } Test( int v ) : i( v ) { cout << "constructeur" << endl; } ~Test() { cout << "destructeur" << endl; } friend ostream& operator<<( ostream& os, Test* t ) { return os << "Test avec la valeur " << t->i << endl; } friend ostream& operator<<( ostream& os, Test t ) { return os << "Test avec la valeur " << t.i << endl; } };
  • 55. Cours semaine 2 jour 1 Cours C++ 55 Création dynamique d’objets (7) void main() { … cout << "t3" << endl; Test* t3 = new Test[ 3 ]; cout << "t3" << t3[ 1 ]; delete []t3; cout << "t4" << endl; Test* t4 = new Test[ 4 ]; cout << "t4[ 0 ] " << t4[ 0 ]; cout << "t4[ 3 ] " << t4[ 3 ]; cout << "t4[ 1 ] " << t4[ 1 ]; delete [ 2 ]t4; // compatibilité avec l'ancien C++ cout << "t4[ 1 ] " << t4[ 1 ]; // ne marche pas (plus ?) cout << "t4[ 3 ] " << t4[ 3 ]; // ne marche pas non plus }
  • 56. Cours semaine 2 jour 1 Cours C++ 56 Création dynamique d’objets (8)  Puisque new et delete sont des opérateurs, il est possible de les surcharger  Comme les autres…  Les signatures standard de ces deux opérateurs, définis au niveau global, sont :  void* operator new( size_t sz );  aussi : void* operator new( size_t sz, void* loc );  void operator delete( void* m );
  • 57. Cours semaine 2 jour 1 Cours C++ 57 Création dynamique d’objets (9) … class Test { … void* operator new( size_t sz ) { cout << "new " << sz << endl; return ::new char[ sz ]; } void operator delete( void* p ) { ::delete []p; } void* operator new[]( size_t sz ) { cout << "new[] " << sz << endl; return ::new char[ sz ]; } void operator delete[]( void* p ) { ::delete []p; } };
  • 58. Cours semaine 2 jour 1 Cours C++ 58 Création dynamique d’objets (10) void main() { cout << "ta" << endl; Test* ta = new Test( 24 ); cout << "ta " << ta; delete ta; cout << "tb" << endl; Test* tb = new Test[ 24 ]; cout << "tb " << tb[ 8 ]; delete []tb; }
  • 59. Cours semaine 2 jour 1 Cours C++ 59 Dynamic binding  Lors du développement d’un système orienté objet, il est fréquent d’avoir besoin d’un ADT mais pas nécessairement de connaître son implémentation  C’est le but d’un ADT après tout…  Un développeur peut également avoir besoin d’un algorithme sans avoir besoin des détails  Pour réaliser un tri par exemple
  • 60. Cours semaine 2 jour 1 Cours C++ 60 Dynamic binding (2)  Dans les cas mentionnés, il peut être préférable de retarder le choix d’une implémentation le plus longtemps possible  La décision n’est prise que lorsque qu’un ensemble d’informations est disponible pendant le traitement  Dans ces cas, il peut être intéressant de mettre en place un système d’appel dynamique, utilisé à l’exécution et non à la compilation
  • 61. Cours semaine 2 jour 1 Cours C++ 61 Dynamic binding (3)  Le mécanisme utilisé s’appelle le dynamic binding (liaison dynamique)  Ce n’est pas une création dynamique d’objet (on parle alors de dynamic linking)  Il s’agit d’une variante moins puissante des pointers to members (member functions) mais cette variante est plus compréhensible
  • 62. Cours semaine 2 jour 1 Cours C++ 62 Dynamic binding (4)  Le dynamic binding repose sur la possibilité de tout de même appeler des fonctions virtuelles, c’est à dire des fonctions dont on ne possède que la signature  Nous reviendrons sur l’héritage demain…
  • 63. Cours semaine 2 jour 1 Cours C++ 63 Dynamic binding (5)  Le dynamic binding améliore la flexibilité et l’extensibilité  Flexibilité : il permet de recombiner des composants existants dans des configurations différentes  Extensibilité : il facilite l’intégration de nouveaux composants dans un système existant
  • 64. Cours semaine 2 jour 1 Cours C++ 64 Dynamic binding (6) // signature de la classe mère class Mere { public: virtual int vfonc( void ); }; // dans le code, on utilise un pointeur sur la classe Mere Mere *mp = /* pointeur vers la classe fille */ mp->vfonc();
  • 65. Cours semaine 2 jour 1 Cours C++ 65 Dynamic binding (7)  La classe mère possède une fonction virtuelle qui sera implémentée de manière différente dans les classes filles  Il est cependant possible de l’utiliser  Rappelez vous de la fonction seDéplacer() sur les Mammifères…
  • 66. Cours semaine 2 jour 1 Cours C++ 66 Dynamic binding (8) // signature de la classe fille (qui hérite de la mère) class Fille : public Mere { public: int vfonc( void ); }; // pointeur sur la classe Mere contenant un pointeur // vers une instance de la classe Fille Fille f; mp = &f; mp->vfonc();
  • 67. Cours semaine 2 jour 1 Cours C++ 67 Dynamic binding (9)  Problèmes posés dans ce cas par les mécanismes d’héritage  Le dynamic binding peut être utilisé pour les fonctions publiques (utilisation de l’extérieur)  Il est possible que des fonctions appelées par la fonction considérée soient implémentées de manière différente dans la classe mère et la classe fille
  • 68. Cours semaine 2 jour 1 Cours C++ 68 Dynamic binding (10)  Ces désavantages sont contournés par le static binding  La liaison est faite pendant la compilation  Aucune flexibilité puisqu’aucun choix ne peut être fait pendant l’exécution  Cela a été fait statiquement, « syntaxiquement »  Le static binding est aussi plus rapide : le type de l’objet par lequel on appelle la fonction est connu
  • 69. Cours semaine 2 jour 1 Cours C++ 69 Dynamic binding (11)  Pour le dynamic binding, il faut identifier le type de l’objet pendant l’exécution pour savoir où se trouve la méthode à appeler effectivement  L’identification de type pendant l’exécution s’appelle le RunTime Type Identification, RTTI  Après la RTTI, il est possible d’envoyer le bon message à la bonne instance pour exécuter la bonne méthode
  • 70. Cours semaine 2 jour 1 Cours C++ 70 Dynamic binding (12)  Le fait de retrouver, à partir d’un objet général, le type spécifique de l’instance courante et d’exécuter la bonne méthode correspond également à du downcasting  Pour analogie, dans un diagramme de classes UML, pour retrouver la classe fille à partir de la classe mère générale, il faut parcourir l’arborescence vers le bas
  • 71. Cours semaine 2 jour 1 Cours C++ 71 Dynamic binding (13)  Le dynamic binding est un mécanisme véritablement objet  Même s’il est aussi facilement relié aux ADT  Le static binding est un mécanisme typiquement associé aux langages de troisième génération (avec appel de procédures et de fonctions)
  • 72. Cours semaine 2 jour 1 Cours C++ 72 Questions / Remarques