Professional Documents
Culture Documents
Thierry Vaira
BTS IRIS Avignon
tvaira@free.fr v0.1
Sommaire
1 2 3 4 5 6 7
Classes et objets Les objets constants Surcharge des oprateurs Lhritage Les exceptions Polymorphisme Transtypage
Cours C/C++
tvaira@free.fr
v0.1
2 / 69
Classes et objets
Classes et objets
Les classes sont les lments de base de la programmation oriente objet (POO) en C++. Dans une classe, on runit :
- des donnes variables : les donnes membres, ou les attributs de la classe. - des fonctions : les fonctions membres, ou les mthodes de la classe.
Une classe A apporte un nouveau type A ajout aux types (pr)dnis de base par C++. Une variable a cre partir du type de classe A est appele instance (ou objet) de la classe A. Exemple (non compilable*) :
class A; // dclare une classe A (* car elle nest pas dfinie) A a1; // instancie un objet a1 de type A A a2; // cre une instance a2 de type A
Cours C/C++
tvaira@free.fr
v0.1
3 / 69
Classes et objets
tat et comportement
Une classe se dclare dans un chier .h. La dclaration permet de connatre les types des choses constituant la classe, et ainsi de lutiliser. Une classe se dnit dans un chier .cc ou .cpp. La dnition permettra de fabriquer les choses constituant la classe. Un objet possdera une identit qui permet de distinguer un objet dun autre objet (son nom, une adresse mmoire). Un objet possdera un tat (les valeurs contenues dans les attributs propres cet objet). Un objet possdera un comportement (lutilisation de ses mthodes lui fera changer dtat).
Cours C/C++
tvaira@free.fr
v0.1
4 / 69
Classes et objets
Il existe une rgle de POO qui prcise que les attributs doivent tre encapsules dans la classe pour viter une utilisation extrieure. Cest une forme de protection permettant dviter une utilisation incorrecte ou non prvue par le programmeur de la classe. On appliquera ce principe en dclarant lensemble des attributs en private.
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 5 / 69
Classes et objets
Cours C/C++
tvaira@free.fr
v0.1
6 / 69
Classes et objets
Constructeur
Un constructeur est charg dinitialiser une instance (objet) de la classe. Il est appel automatiquement au moment de la cration de lobjet. Un constructeur est une mthode qui porte toujours le mme nom que la classe. Il existe quelques contraintes :
Il peut avoir des paramtres, et des valeurs par dfaut. Il peut y avoir plusieurs constructeurs pour une mme classe. Il na jamais de type de retour.
Cours C/C++
tvaira@free.fr
v0.1
7 / 69
Classes et objets
Destructeur
Le destructeur est la mthode membre appele lorsquune instance (objet) de classe cesse dexister en mmoire. Son rle est de librer toutes les ressources qui ont t acquises lors de la construction (typiquement librer la mmoire qui a t alloue dynamiquement par cet objet). Un destructeur est une mthode qui porte toujours le mme nom que la classe, prcd de "~". Il existe quelques contraintes :
Il ne possde aucun paramtre. Il ny en a quun et un seul. Il na jamais de type de retour.
Voil, on sait susamment de choses pour crire notre premire classe et instancier nos premiers objets.
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 8 / 69
Classes et objets
Cours C/C++
tvaira@free.fr
v0.1
9 / 69
Classes et objets
Cours C/C++
tvaira@free.fr
v0.1
10 / 69
Classes et objets
Cours C/C++
tvaira@free.fr
v0.1
11 / 69
Classes et objets
du destructeur ~Point : jai rien faire du destructeur ~Point : jai rien faire
Cours C/C++ tvaira@free.fr v0.1 12 / 69
Classes et objets
new et delete
Pour allouer dynamiquement en C++, on utilisera loprateur new. Celui-ci renvoyant une adresse o est cre la variable en question, il nous faudra un pointeur pour la conserver. Manipuler ce pointeur, reviendra manipuler la variable alloue dynamiquement. Pour librer de la mmoire alloue dynamiquement en C++, on utilisera loprateur delete.
Cours C/C++
tvaira@free.fr
v0.1
13 / 69
Classes et objets
Pour allouer dynamiquement un objet, on utilisera loprateur new. Exemple : allocation dynamique dun objet
#include <iostream> #include "point.h" using namespace std; int main() { Point *pointC; // je suis pointeur sur un objet de type Point pointC = new Point(2,2); // jalloue dynamiquement un objet de type Point pointC->afficher(); // Comme pointC est une adresse, je dois utiliser loprateur -> pour accder aux membres de cet objet pointC->setY(0); // je modifie la valeur de lattribut _y de pointB (*pointC).afficher(); // cette criture est possible : je pointe lobjet puis jappelle sa mthode afficher() delete pointC; // ne pas oublier de librer la mmoire alloue pour cet objet return 0; }
Cours C/C++
tvaira@free.fr
v0.1
14 / 69
Classes et objets
Cas particuliers
tableauDe10Points[10]; // dclaration dun tableauDe10Points contenant 10 objets de type Point Point pointE(); return 0; } // que fait cette ligne ?
Cours C/C++
tvaira@free.fr
v0.1
15 / 69
Classes et objets
int mult(int a=2, int b=3) { return a*b; } mult(3,4); // donne 12 mult(3); // quivaut mult(3,3) qui donne 9 mult(); // quivaut mult(2,3) qui donne 6
Remarque : cette possibilit, permet dcrire quun seul constructeur protant du mcanisme de valeur par dfaut.
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 16 / 69
Classes et objets
Deux constructeurs sont toujours ncessaires dans toute nouvelle classe : le constructeur par dfaut et le constructeur de copie. Ils sont tellement importants que si vous ne les crivez pas, le compilateur tentera de le faire votre place ... mais moins de savoir exactement ce que vous faites il vaut mieux les crire soi-mme. Le rle du constructeur par dfaut est de crer une instance non initialise quand aucun autre constructeur fourni nest applicable. Par exemple, le constructeur par dfaut de notre classe Point sera :
Point::Point() {} // Sans aucun paramtre !
Cours C/C++
tvaira@free.fr
v0.1
17 / 69
Classes et objets
Cours C/C++
tvaira@free.fr
v0.1
18 / 69
Classes et objets
Le compilateur na pas trouv de constructeur par dfaut dans notre classe, il faut donc le dclarer et le dnir. Dnition dun constructeur par dfaut sans argument :
Point::Point() { _x=0; _y=0; }
Maintenant, le programme prcdent se compile et le constructeur par dfaut sera appel pour lobjet pointA et 10 fois pour chaque objet Point du tableau.
Cours C/C++
tvaira@free.fr
v0.1
19 / 69
Classes et objets
Le constructeur par dfaut est ncessaire notamment dans : la cration de tableaux dobjet, la fabrication dobjets temporaires et lagrgation par valeur des objets.
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 20 / 69
Classes et objets
Liste dinitialisation
Un meilleur moyen daecter des valeurs lors de la construction aux donnes membres de la classe est la liste dinitialisation. Dans le chier .cc, il sut dutiliser la syntaxe suivante :
Point::Point(int x, int y) : _x(x), _y(y) // cest la liste dinitialisation { /* il ny a rien dautre faire */ }
La liste dinitialisation permet dutiliser le constructeur de chaque donne membre, et ainsi dviter une aectation aprs coup. la liste dinitialisation doit tre utilise pour certains objets qui ne peuvent pas tre contruits par dfaut : cest le cas des rfrences et des objets constants. Important : lordre dinitialisation des membres doit correspondre celui de leurs dclarations dans le chier .h.
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 21 / 69
Classes et objets
Dans certaines conditions particulires, il est ncessaire de disposer dun moyen de dsigner depuis lintrieur dune fonction membre, non pas les donnes membres, mais linstance elle-mme de la classe sur laquelle la mthode membre est appele. Le mot cl "this" permet de dsigner ladresse de linstance (de lobjet) sur laquelle la fonction membre a t appele.
Cours C/C++
tvaira@free.fr
v0.1
22 / 69
Classes et objets
class A { public: // pour lexemple int x; A * getA(); void setX(int); }; void A::setX(int x) { this->x = x; } // Ici this permet de distinguer le paramtre x de lattribut x de lobjet de type A sur lequel on a appel setX A* A::getA() { return this; } // Ici this est ladresse de lobjet de type A sur lequel on a appel getA int main() { A a; A *pa; a.setX(2); pa = a.getA(); // quivalent (trs tordu !) pa = &a ! cout << "x=" << a.x << endl; // Affiche : x=2 cout << "x=" << pa->x << endl; // Affiche : x=2 return 0; }
Cours C/C++
tvaira@free.fr
v0.1
23 / 69
Classes et objets
Agrgation
Lagrgation signie implicitement contient un (ou est compose dun ou possde un ) ou tout simplement a un . On distingue deux types dagrgation : Agrgation interne : lobjet agrg est cr par lobjet agrgateur Agrgation externe : lobjet agrg a t cr extrieurement lobjet agrgateur Il y a 3 possibilits de mise en oeuvre : agrgation par valeur (appele aussi composition) agrgation par rfrence agrgation par pointeur Remarque : en rgle gnrale, le crateur dun objet est le responsable de sa destruction.
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 24 / 69
Classes et objets
class ObjetGraphique { public: ObjetGraphique(Point p, int couleur) : point(p), couleur(couleur) {} void afficher() { cout << point.getX() << "," << point.getY() << " [" << couleur << "]" << endl ; } private: Point point; // par valeur int couleur; }; Point p1(1, 1); ObjetGraphique o1(p1, 1); p1.setX(5); o1.afficher(); // donne : 1,1 [1]
Cours C/C++
tvaira@free.fr
v0.1
25 / 69
Classes et objets
class ObjetGraphique { public: ObjetGraphique(Point &p, int couleur): point(p), couleur(couleur) {} void afficher() { cout << point.getX() << "," << point.getY() << " [" << couleur << "]" << endl ; } private: Point &point; // par rfrence int couleur; }; Point p1(2, 2); ObjetGraphique o1(p1, 1); p1.setX(5); o1.afficher(); // donne : 5,2 [1]
Cours C/C++
tvaira@free.fr
v0.1
26 / 69
Classes et objets
Classes et objets
Remarque : toute autre duplication (au cours de la vie dun objet) sera faite par loprateur daectation (=).
Cours C/C++
tvaira@free.fr
v0.1
28 / 69
Classes et objets
Lobjet modle est pass : en rfrence, ce qui assure de bonnes performances et empche un bouclage inni et la rfrence est constante, ce qui garantit que seules des mthodes constantes (ne pouvant pas modier les attributs) seront appelables sur lobjet pass en argument
Cours C/C++
tvaira@free.fr
v0.1
29 / 69
Classes et objets
Remarque : le compilateur fournit un constructeur de copie automatique par recopie bit bit optimise .
tv (BTS IRIS Avignon) Cours C/C++ v0.1 30 / 69
tvaira@free.fr
Classes et objets
Cours C/C++
tvaira@free.fr
v0.1
31 / 69
Classes et objets
Cours C/C++
tvaira@free.fr
v0.1
32 / 69
Classes et objets
Destructeur
On aura besoin de dnir son destructeur ds lors que la classe ralise de : lagrgation par pointeur lallocation dynamique de mmoire Exemple dun destructeur basique :
A::A() { t = new int[10]; // allocation dynamique point = new Point; // agrgation par pointeur avec allocation dynamique } A::~A() { delete [] t; // on libre delete point; // on libre }
Cours C/C++
tvaira@free.fr
v0.1
33 / 69
Classes et objets
Remarque : Cet oprateur renvoie une rfrence sur T an de pouvoir lutiliser avec dautres aectations.
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 34 / 69
Classes et objets
Rappel : loprateur daectation est associatif droite a=b=c est value comme a=(b=c). Ainsi, la valeur renvoye par une aectation doit tre son tour modiable.
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 35 / 69
Classes et objets
Une classe T est dite sous forme canonique (ou forme normale ou forme standard) si elle prsente les mthodes suivantes :
class T { public: T (); // Constructeur par dfaut T (const T&); // Constructeur de copie ~T (); // Destructeur ventuellement virtuel T &operator= (const T&); // Operateur daffectation };
Cours C/C++
tvaira@free.fr
v0.1
36 / 69
Objets constants
Les rgles suivantes sappliquent aux objets constants : On dclare un objet constant avec le modicateur const On ne peut appliquer que des mthodes constantes sur un objet constant Un objet pass en paramtre sous forme de rfrence constante est considr comme constant Remarque : une mthode constante est tout simplement une mthode qui ne modie aucun des attributs de lobjet. Il est conseill de qualier const toute fonction qui peut ltre.
Cours C/C++
tvaira@free.fr
v0.1
37 / 69
Mthodes constantes
La qualication const dune fonction membre fait partie de sa signature. Ainsi, on peut surcharger une fonction membre non constante par une fonction membre constante :
class Point { private: int x, y; public: int X() const { return x; } int Y() const { return y; } int& X() { return x; } int& Y() { return y; } void afficher() { cout << X() << "," << Y() << endl ; } }; Point p1(1, 0); p1.afficher(); // donne : 1,0 int r; r = p1.X(); p1.Y() = r; p1.afficher(); // donne : 1,1
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 38 / 69
Attributs constants
Une donne membre dune classe peut tre qualie const. Il est alors obligatoire de linitialiser lors de la construction dun objet, et sa valeur ne pourra par la suite plus tre modie.
class Point { private: const char lettre; int x, y; public: Point(char lettre, int x, int y):lettre(lettre), x(x), y(y) ... void afficher() { cout << lettre << ":" << X() << "," << Y() << endl ; } }; Point p1(A, 1, 0); p1.afficher(); // donne : A:1,0
Cours C/C++
tvaira@free.fr
v0.1
39 / 69
La surcharge doprateur permet aux oprateurs du C++ davoir une signication spcique quand ils sont appliqus des types spciques. Parmi les nombreux exemples que lon pourrait citer : myString + yourString pourrait servir concatner deux objets string maDate++ pourrait servir incrmenter un objet Date a * b pourrait servir multiplier deux objets Nombre e[i] pourrait donner accs un lment contenu dans un objet Ensemble
Cours C/C++
tvaira@free.fr
v0.1
40 / 69
Cours C/C++
tvaira@free.fr
v0.1
42 / 69
Remarque : Les oprateurs de comparaison sont trs simples surcharger. La seule chose essentielle retenir est quils renvoient une valeur boolenne.
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 43 / 69
A Op B se traduit par operatorOp(A, B) // Dans une classe T : friend T operator+(const T &a, const T &b); // Et globalement : T operator+(const T &a, const T &b) { T result = a; return result += b; }
Cours C/C++
tvaira@free.fr
v0.1
44 / 69
Lavantage de cette syntaxe est que loprateur est rellement symtrique, contrairement ce qui se passe pour les oprateurs dnis lintrieur de la classe. On constate que les oprateurs externes doivent tre dclars comme tant des fonctions amies (friend) de la classe sur laquelle ils travaillent, faute de quoi ils ne pourraient pas manipuler les donnes membres de leurs oprandes.
Cours C/C++
tvaira@free.fr
v0.1
45 / 69
Les oprateurs dincrmentation et de dcrmentation ont la mme notation mais reprsentent deux oprateurs en ralit. En eet, ils nont pas la mme signication, selon quils sont placs avant ou aprs leur oprande. Ne possdant pas de paramtres (ils ne travaillent que sur lobjet), il est donc impossible de les direncier par surcharge. La solution qui a t adopte est de les direncier en donnant un paramtre ctif de type int lun dentre eux.
oprateurs prxs : ++ et ne prennent pas de paramtre et doivent renvoyer une rfrence sur lobjet lui-mme oprateurs suxs : ++ et prennent un paramtre int ctif (que lon nutilisera pas) et peuvent se contenter de renvoyer la valeur de lobjet
Cours C/C++
tvaira@free.fr
v0.1
46 / 69
// Oprateur prfixe : T &T::operator++(void) { ++x ; // incrmente la variable return *this ; // et la retourne } // Oprateur suffixe : retourne la valeur et incrmente la variable T T::operator++(int n) { // cre un objet temporaire, T tmp(x); // peut nuire gravement aux performances ++x; return tmp; }
Cours C/C++
tvaira@free.fr
v0.1
47 / 69
// Oprateur prfixe T operator++(T &a) { ++a.x; return a; } // Oprateur suffixe T operator++(T &a, int n) { T tmp = a; ++a.x; return tmp; }
Cours C/C++
tvaira@free.fr
v0.1
48 / 69
Lhritage
Lhritage (1/2)
Lhritage (ou spcialisation, ou drivation) permet dajouter des proprits une classe existante pour en obtenir une nouvelle plus prcise. Lide est : "un B est un A avec des choses en plus".
Exemple : Un tudiant est une personne, et a donc un nom et un prnom. De plus, il a un numro INE.
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 49 / 69
Lhritage
Lhritage (2/2)
// A est la classe parente ou mre de B (en anglais superclass) class A { public: void f(); }; // B est la classe fille ou drive de A : B hrite ou descend de A class B : public A { public: void g(); }; A a; B b; a.f(); b.g(); b.f(); a.g(); // // // // legal : legal : legal : illegal a b b : est un A est un B est un A (par hritage) a na pas de membre g() car a nest pas un B
Cours C/C++
tvaira@free.fr
v0.1
50 / 69
Lhritage
Conversion automatique
Si B hrite de A, alors toutes les instances de B sont aussi des instances de A, et il est donc possible de faire :
A a; B b; a = b; // Proprit conserve lorsquon utilise des pointeurs : A *pa; B *pb=&b; pa = pb;//car pointer sur un B cest avant tout pointer sur un A // videment, linverse nest pas vrai : A a; B b; b = a; // ERREUR ! // Pareil pour les pointeurs : A *pa=&a; B *pb; pb=pa;//ERREUR : car pointer sur un A nest pas pointer sur un B
Conclusion : Traiter un type driv comme sil tait son type de base est appel transtypage ascendant ou surtypage (upcasting ). A loppos, les transtypage descendant (downcast ) posent un problme particulier car leur vrication nest possible qu lexcution. Ils ncessitent lutilisation doprateur de cast : dynamic_cast (vu plus tard).
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 51 / 69
Les exceptions
Dcoupage du traitement derreur en deux parties : le dclenchement : instruction throw le traitement : deux instructions insparables try et catch
Cours C/C++
tvaira@free.fr
v0.1
52 / 69
Les exceptions
Les exceptions
Cours C/C++
tvaira@free.fr
v0.1
54 / 69
Les exceptions
Cours C/C++
tvaira@free.fr
v0.1
55 / 69
Les exceptions
Cours C/C++
tvaira@free.fr
v0.1
56 / 69
Les exceptions
Mais, le spcicateur dexception interdit aux autres mthodes (ou fonctions) appeles dinvoquer des exceptions non prvues. Hors, ce point est dicile vrier lors de la compilation. Aussi, les spcicateurs dexception doivent ils tre rservs au code matris totalement et plus spciquement aux mthodes pour lesquelles on est en mesure de prvoir le droulement complet.
tv (BTS IRIS Avignon) Cours C/C++ tvaira@free.fr v0.1 57 / 69
Polymorphisme
Cours C/C++
tvaira@free.fr
v0.1
58 / 69
Polymorphisme
Polymorphisme
Cours C/C++
tvaira@free.fr
v0.1
60 / 69
Polymorphisme
On dclare quon veut une fonction qui ait la exibilit des proprits de lassociation tardive en utilisant le mot-cl virtual. On na pas besoin de comprendre les mcanismes de virtual pour lutiliser, mais sans lui on ne peut pas faire de la programmation oriente objet en C++. En C++, on doit se souvenir dajouter le mot-cl virtual (devant une mthode) parce que, par dfaut, les fonctions membres ne sont pas lies dynamiquement. Les fonctions virtuelles permettent dexprimer des dirences de comportement entre des classes de la mme famille. Ces dirences sont ce qui engendre un comportement polymorphe.
Cours C/C++
tvaira@free.fr
v0.1
61 / 69
Polymorphisme
Cours C/C++
tvaira@free.fr
v0.1
62 / 69
Polymorphisme
Cours C/C++
tvaira@free.fr
v0.1
63 / 69
Polymorphisme
Lexcution du programme dessai nous montre que nous nobtenons pas un comportement polymorphe puisque cest la mthode dessiner() de la classe Forme qui est appele :
constructeur Forme constructeur Forme je dessine ... une je dessine ... une <|- Cercle <|- Triangle forme ? forme ?
Cours C/C++
tvaira@free.fr
v0.1
64 / 69
Polymorphisme
tvaira@free.fr
Polymorphisme
Cours C/C++
tvaira@free.fr
v0.1
66 / 69
Polymorphisme
Lexcution du programme dessai nous montre maintenant que nous obtenons un comportement polymorphe puisque cest la bonne mthode dessiner() qui est appele :
constructeur Forme <|- Cercle constructeur Forme <|- Triangle je dessine un Cercle ! je dessine un Triangle !
Cours C/C++
tvaira@free.fr
v0.1
67 / 69
Transtypage
Le transtypage en C++
Le transtypage (cast ou conversion de type) en C++ permet la conversion dun type vers un autre. Nouvelle syntaxe de loprateur traditionnel :
En C : (nouveau type)(expression transtyper) ; En C++ : type(expression transtyper) ;
Cours C/C++
tvaira@free.fr
v0.1
68 / 69
Transtypage
Traiter un type driv comme sil tait son type de base est appel transtypage ascendant, surtypage ou gnralisation (upcasting ). Cela ne pose donc aucun problme. Exemple : transtypage ascendant
class Forme {}; class Cercle : public Forme {}; class Triangle : public Forme {} ; void faireQuelqueChose(Forme &f) { f.dessiner(); } ... Cercle c; // Un Cercle est ici pass une fonction qui attend une Forme. // Comme un Cercle est une Forme, il peut tre trait comme tel par faireQuelqueChose() faireQuelqueChose(c);
Cours C/C++
tvaira@free.fr
v0.1
69 / 69