Plan G n ral e e
1 Pr sentation du C++ e 2 Notion de r f rence ee 3 Fonctions : arguments et surcharge 4 Allocation dynamique 5 Constructeur dune classe vecteur 6 Constructeur dune classe matrice 7 H ritage e 8 G n ricit et template e e e
1- G. Pr vost @ Universit du Havre e e
1. Pr sentation de C++ e
1 Introduction 2 Incompatibilit s C et C++ e 3 Quelques sp cicit s e e 4 C++ langage orient objet e
1.1 Introduction
1982 par Bjarne Stroustrup (AT&T laboratory) ;
Introduction
Quattend-on dun programme ? ` Exactitude : aptitude dun programme a fournir un r sultat e donn dans des conditions sp ci es. e e e
La robustesse : le programme doit bien r agir lorsquon e s loigne des conditions normales dutilisation. e Lextensibilit : le programme doit pouvoir etre modi e e pour satisfaire aux evolutions des sp cications. e
La r utilisabilit : possibilit dutiliser des parties dun e e e programme pour traiter dautres probl` mes. e La portabilit : Un programme d velopp pour un e e e processeur et un syst` me dexploitation doit pouvoir etre e utilis sur un autre processeur et/ou un autre syst` me e e dexploitation. Lefcacit : Le code doit etre sufsamment rapide. e
Pr sentation de C++ e
Les solutions propos es : e La programmation structur e e Algorithmes + Structures de donn es = Programmes e dapr` s N. Wirth (Pascal). e
La programmation structur e + les types abstraits de e donn es. e La programmation orient e objet (POO) e
Pr sentation de C++ e
Quest-ce quun objet ? cest une association de : Donn es stock es dans des attributs ; e e Fonctions appel es m thodes qui agissent sur ces donn es. e e e
Les objets (en th orie) respectent le principe dencapsulation : e Attributs non directement accessibles ... acc` s gr ce a des e a ` m thodes pour consultation ou modication. e
` Lappel dune m thode correspond a un envoi de message e ` a lobjet. Ces m thodes jouent un r le dinterface. e o
Pr sentation du C++ e
Quest-ce quune classe ? G n ralisation de la notion de type. e e Description dun ensemble dobjets qui poss` dent une e structure de donn es identique et qui disposent des e m mes m thodes. e e Un objet est une instance de sa classe. ` Les donn es sont propres a chaque objet (en g n ral). e e e ` Une classe peut etre d nie a laide dune autre classe. e Elle h rite des propri t s et des aptitudes de la e ee premi` re. e
9- G. Pr vost @ Universit du Havre e e
Utilisation de const ; Convertions avec le pointeur g n rique void *. e e Pour le reste, sauf pr cision contraire, le C++ contient le C. e
D nition de fonctions e
En C, vous pouvez utiliser une fonction qui na pas fait lobjet dune d nition ou dun prototypage. La fonction e retourne alors un int. En C++, toute fonction doit etre d nie avec la pr cision e e du type de ses arguments et de sa valeur de retour.
En C++ : float sansarg(); En C : float sansarg(void); Une fonction qui ne retourne rien en C++ : void sansretour(int x);
Utilisation de const
Port e : e En C et C++, const d signe un identicateur dont la e valeur ne peut pas changer. const appliqu a une variable locale, la port e est e` e limit e au bloc dans lequel sest effectu e la e e d claration. e const appliqu a une variable globale, C++ limite la e` port e au chier source. e
En C++, seule la convertion dun pointeur quelconque vers void * est accept e sans op rateur de cast : e e
gen = adi; \\accepte e adi = gen; \\refuse e adi = (int*) gen; \\accepte e
A celle-ci sajoute, les commentaires de n de ligne qui d marrent par // et vont jusqu` la n de ligne. e a
void main() { int i=0; // i est une variable enti`re e ... }
Remarques : Les anciennes fonctions sont toujours utilisables ; Lop rateur de r f rence & nest pas n cessaire pour la e ee e saisie ; Un processus de v rication automatique de type permet e de saffranchir des multiples formats de type tr` s utilis s e e en C.
Libert dans lemplacement des d clarations ; e e Notion de r f rence ; ee Surcharge de fonction ; Allocation dynamique par les op rateurs new et delete ; e Fonction inline.
Nouvelles possibilit es offertes par lorientation objet : e Notion de classe ; M canisme dinstanciation (cr ation dobjet) ; e e Constructeur/ Destructeur ; Fonction amies ; Surcharge dop rateurs ; e Red finition de conversions ; e H ritage - h ritage multiple ; e e Notion de ot.
2. Notion de r f rence ee
1 D nition e 2 D claration et initialisation e 3 Transmission par r f rence ee
2.1 D nition e
R f rence : nouveau type qui permet de manipuler un ee alias sur une autre variable existante.
Toute action sur un alias est effectu e sur lentit a laquelle e e` lalias fait r f rence. ee Notion de r f rence proche de la notion de pointeur ee Une variable de type pointeur pointe sur une autre entit ; e ` Une variable de type r f rence fait r f rence a une ee ee autre entit . e R f rence = pointeur cach . ee e
Une r f rence s crit : type & ; ee e Exemple : int & r f rence sur un int ; ee int* & r f rence sur un int*. ee
= 0; ref_x = x;
Pour modifier un param` tre appelant on transmet la e valeur de son adresse. On manipule alors le pointeur au niveau de la fonction.
En C++
Transmission par valeur ; Transmission par r f rence. Les modifications portent sur ee le param` tre dappel et non sur une copie. e Exemple : prog4.cc La trace dex cution : traceprog4 e
Le code : prog6.cc print() et affiche() fournissent le m me r sultat e e Dans le cas de print() on passe la valeur de S_tableau t ce qui n cessite une recopie de e nb_elt et de tab. Dans le cas daffiche() on transmet une r f rence ee constante de t. t ne peut pas etre modifi e. e
Lorsquune d claration pr voit des valeurs par d faut, les e e e arguments concern s sont obligatoirement les derniers de e la liste.
Pour sp cier des arguments par d faut, il faut : e e le type de largument formel ; le nom de largument formel (optionnel) ; = Une expression ne contenant pas darguments formels. Exemples : prog7.cc traceprog7 prog8.cc prog9.cc
Exemple incorrect : prog10.cc Message derreur du compilateur : erreurprog10.txt Une version correcte : prog10bis.cc Avec des pointeurs il est possible dutiliser des variables locales (attention aux adresses folles) prog11.cc
38- G. Pr vost @ Universit du Havre e e
Quel est le r sultat de ce programme ? : prog13.cc e Il afche 2. Quel est le r sultat de ce programme ? : prog13bis.cc e Il afche 3.
int& place (int tab[L][C], int val) { for (int i=0; i<L; i++) for (int j=0; j<C; j++) if (tab[i][j] == val) return tab[i][j]; return tab[0][0]; } void ecrire (int tab[L][C]) { for (int i=0; i<L; i++) { for (int j=0; j<C; j++) cout << tab[i][j] << "/"; cout << endl; } }
R sultats afch s : e e
0/2 1/3 2/4 0/2 1/0 2/4
Le compilateur identie la fonction appel e grace aux e types des arguments ; Les types doivent etre discriminants ;
4. Allocation dynamique
1 Organisation de la m moire e 2 Lop rateur new e 3 Lop rateur delete e 4 Exemple developp e 5 Tableaux
Une zone de m moire statique dans laquelle on trouve les e variables statiques et les variables globales (dur e de vie = e celle du processus). ` La pile qui sert a stocker les variables automatiques.Dans cette zone les variables sont constamment cr ees et e d truites en fonction de la dur e de vie. e e
Le tas cest dans cette zone que lon r serve un e emplacement m moire. On connat cet emplacement par e son adresse et non par un identificateur. Lemplacement e e est r serv tant quil na pas et d sallou . On utilise new e e e et delete pour g rer cet emplacement. e
e el ment.
Exemple
int *ptr = new int; //... delete ptr;
Pour d sallouer un tableau : e delete adresse Pour d sallouer un tableau dobjets : e delete [] adresse Exemple
int *tab = new int[10]; //... delete tab;
Le tableau est allou dynamiquement ; e Les chanes egalement ; A la fin du programme on d salloue. e exemple : prog18.cc et sa trace traceprog18.txt.
e Les el ments sont des tableaux dentiers, ptr est donc un pointeur sur un tableau de NB COL entiers ; Toutes les dimensions doivent etre connue sauf eventuellement la premi` re. e Pour lib rer la zone : delete [] ptr; e Exemple prog19.cc
int **
int *
..........
Exemple : prog20.cc
54- G. Pr vost @ Universit du Havre e e
Exemple
Voici la premi` re version de notre chier vecteur.h, en-t te e e de la classe Vecteur :
#include <iostream.h> class Vecteur { int taille; float* valeur; public : void initialise (int, float); void ajoute (int, float); void affiche (); };
Voici maintenant le chier vecteur.cc qui contient limpl mentation des m thodes d nies dans le chier e e e den-t te (on notera la mani` re de d signer les m thodes e e e e rattach es aux classes) : e
void Vecteur::initialise (int a, float b) { taille = a; valeur = new float[taille]; for (int i=0; i < taille; i++) valeur[i] = b; } void Vecteur::affiche() { for (int i=0; i < taille; i++) cout << valeur[i] << ; cout << endl; }
void Vecteur::ajoute(int i, float a) { valeur[i] += a; } main() { Vecteur v; v.initialise (10, 3.0); v.affiche(); v.ajoute (3, 2.0); v.affiche(); }
Remarque : Dans la construction nale de la classe Vecteur, ces m thodes nexisteront pas ou seront trait es diff remment. e e e
Le pointeur this
Chaque classe poss` de implicitement (sans que lon ait e besoin de la d clarer) la donn e qui correspond au e e pointeur this qui pointe sur lobjet courant.
Attention : Cette m thode ne teste pas si lobjet P a les m mes e e composantes que lobjet courant !
Membres static
Un membre peut etre d clar static. e e ` Il est alors commun a tous les objets de la classe. Si un objet le modie, il le sera donc pour tous les autres objets de la classe.
qui va compter le nombre dobjets instanci s de la classe : e On linitialise en dehors de la d claration de classe par e
int Vecteur::nb_objet=0;
Remarque : on pr xe lattribut par le nom de la classe et e pas par le nom dun objet instanci . Par d faut une e e variable static est initialis e a 0. e ` On lincr mente dans la proc dure initialise par e e linstruction
Vecteur::nb_objet++;
5.2 Constructeurs/destructeurs
A linstanciation dun objet, une fonction membre appel e e constructeur est invoqu e automatiquement. e Lorsque lobjet nexiste plus, une fonction membre appel e destructeur est invoqu e automatiquement. e e On peut red nir soi-m me un ou des constructeurs ou e e destructeurs. Un constructeur (resp. destructeur) est donc une focntion membre public qui porte obligatoirement le nom de la classe.
Constructeurs - exemple 1
Dans la classe Vecteur, la fonction initialise peut etre avantageusement remplac e par un constructeur : e
class Vecteur { int taille; float* valeur; public: Vecteur(int, float); void ajoute(int, float); void affiche(); }
Vecteur::Vecteur(int a, float b) { taille = a; valeur ) new float [taille]; for (int i=0; i<taille; i++) valeur[i]=b; } ... main() { Vecteur v(10, 3.0); v.affiche(); }
Remarque : il peut y avoir plusieurs affectations successives, s par es par des virgules. e e
` Par exemple, on pourrait ajouter a la classe Vecteur un constructeur sans param` tre. Linstantiation invoquera la e classe sans mettre de paranth` se. e
Vecteur::Vecteur() { taille=0; valeur = new float; } main() { Vecteur p; ...}
Destructeur
Dans la classe Vecteur, on va d nir un destructeur qui e lib` re la zone m moire allou e par le constructeur. Il sexecute e e e ` ` e a la n du programme ou dun bloc ou des objets locaux ont et d nis. e
class Vecteur { int taille; float* valeur; public : Vecteur (int, float); Vecteur(); } Vecteur::Vecteur() { delete valeur; }
Constructeur de copie
Dans les cas suivants : linitialisation dun objet par un autre,
on appelle implicitement une m thode pr d nie qui est en fait e e e un constructeur de copie.
On peut cr er soi-m me son propre constructeur de copie. e e Cest n cessaire lorsque lobjet contient des pointeurs et e des structures dynamiques. Par exemple, pour la classe vecteur, le constructeur de recopie va uniquement recopier ladresse du tableau point e par le vecteur (voir gure).
En raison du destructeur ecrit pr c demment, on peut e e rencontrer le probl` me suivant : e Si la copie concerne une transmission de param` tre, e
` a lappel de la fonction, un vecteur local est cr e, e son attribut valeur pointe sur la m me adresse que e lobjet initial. A la sortie de la fonction, le destructeur de ce vecteur local est invoqu e et provoque la d sallocation de la zone m moire point e e e e par valeur ` et donc celle qui correspond aussi a lobjet initial !
Il est n cessaire d crire soi-m me son constructeur de copie e e e qui fera une nouvelle allocation pour le vecteur recopi . On e doit alors recopier les valeurs point es dans le nouvel e emplacement (voir gure).
Objet initial float* valeur; 1.0 7.0 3.0
Un constructeur de recopie devra obligatoirement etre d ni e par le prototype suivant : Vecteur (Vecteur &) ou encore Vecteur (const Vecteur &) car il ny a pas lieu de modier le param` tre transmis. e
#include <iostream.h> class Vecteur { int taille; float* valeur; public : Vecteur(int n=0) //constructeur ... //sous sa forme finale { valeur = new float [taille=n];}
Vecteur (const Vecteur & v) // const. par recopie { valeur = new float [taille=v.taille]; for (int i=0; i<taille; i++) valeur [i] = v.valeur[i]; } Vecteur() { delete valeur;} };
Remarque : Le corps des fonctions est directement ecrit dans la d claration de la classe. Il sagit de fonctions inline. e
` Pour r aliser cela, on ajoute une m thode a la classe e e vecteur qui sappelle operator+.v1 + v2 doit donc etre interpr t sous la forme v1.operator+(v2). ee
class Vecteur { ... Vecteur operator+ (const Vecteur &); ... } Vecteur Vecteur::operator+ (const Vecteur &v) // on suppose que la taille de v est // identique au vecteur courant { Vecteur result(taille); for (int i=0; i<taille; i++) result.valeur[i]=valeur[i]+v.valeur[i]; return result; }
Remarques : 1. Les param` tres sont transmis par r f rence (constante) e ee pour eviter les recopies des tableaux. 2. Attention de ne pas renvoyer une r f rence de vecteur : ee Vecteur & Vecteur::operator+ (const Vecteur &v) car on renvoie ici ladresse du vecteur local result qui est d sallou en n dex cution ! e e e
3. On peut aussi d nir lop rateur + en dehors de la classe e e Vecteur, pour une m me utilisation e
Vecteur operator+ (const Vecteur &v1, const Vecteur &v2) // on suppose que les tailles de v1 et // de v2 identiques { Vecteur result(v1.taille); for (int i=0; i<v1.taille; i++) result.valeur[i]=v1.valeur[i]+v2.valeur[i]; return result; }
On suppose ici que les attributs des vecteurs sont publiques, sinon on utilise des op rateurs dacc` s, comme e e d crit plus loin. e
82- G. Pr vost @ Universit du Havre e e
Comme pour le constructeur de recopie existant par d faut, e lop rateur daffectation peut poser des probl` mes avec les e e structures dynamiques.
Alors les attributs valeur de b et a pointent sur la m me e zone m moire. Une supression de b va d sallouer le e e tableau g r aussi par a ! ee
Remarque : 1. La transmission de largument doit se faire par r f rence ee car on a besoin de ladresse dans le test (this != &v) qui evite que lon affecte un objet sur lui-m me et eviter e notamment de faire delete valeu; qui efface tout ! 2. Le qualicatif const devant le param` tre permet e daffecter aussi des vecteurs constants (sinon cest impossible). 3. Lop rateur daffectation renvoie une adresse pour e permettre des affectations multiples : v1 = v2 = v3;
86- G. Pr vost @ Universit du Havre e e
class T { ... public : T(...); //constructeur T(const T &); // constructeur de copie T(); // destructeur T & operator= (const T&); // op. affectation };
On utilise la surcharge de lop rateur [], ainsi a[i] va e d signer l l ment voulu pour a un objet de la classe. e ee
class Vecteur { ... float & operator[] (int); ... } float & Vecteur::operator[](int i) { return valeur[i]; }
Remarques : 1. La m thode renvoie une r f rence. On peut lutiliser dans e ee le membre gauche dune affectation :
Vecteur a; a[6]=3.2;
2. Si on veut utiliser cette fonction sur un objet constant, il ` faut ajouter const a droite de len-t te. Dans ce cas, il e ny a pas lieu de faire daffectation sur une composante de lobjet ! et la focntion na pas besoin de renvoyer une r f rence. On a int r t a red nir une deuxi` me focntion ee ee ` e e dacc` s pour les objets constants : e
class Vecteur { ... float operator[](int) const; ... } float Vecteur::operator[](int i) const { return valeur[i]; }
` 3. On peut a lidentique utiliser lop rateur (). e 4. On peut utiliser lop rateur dacc` s dans la d nition des e e e autres m thodes de la classe. Par exemple, lop rateur + e e peut se r ecrire : e
Vecteur Vecteur::operator+ (const Vecteur &v) { Vecteur result(taille); for (int i=0; i<taille; i++) result[i]=valeur[i]+v[i]; return result; }
Une classe est amie dune autre classe si toutes ses fonctions lui sont amies. La d claration damiti doit se faire dans la classe qui e e autorise les acc` s a ses donn es priv es. e ` e e
Exemple
class A { friend void fonction_b (); friend class C; ... }
Toutes les fonctions de la classe C peuvent acc der aux e donn es priv s de A. e e
` Attention : la notion damiti est contraire a la notion e dencapsulation. Elle doit etre utiliser de mani` re pertinente et e avec parsimonie.
94- G. Pr vost @ Universit du Havre e e
Telle quelle est ecrite, cette fonction acc` de aux donn es e e priv es du vecteur v. Elle doit etre d clar e amie de la classe e e e vecteur comme indiqu ci-apr` s : e e
class Vecteur { ... public : ... friend Vecteur operator* (float, const Vecteur &); ... }
Bien attendu, on peut se dispenser ici de cette d claration e damiti , d nir et utiliser proprement des op rateurs dacc` s. e e e e
` cela correspond a
operator>> (cin, quelque_chose);
Cette fonction, une fois d nie, permettra de saisir des e objets de type tt nom classe, avec linstruction :
in >> ...
Par ailleurs, ce ot dentr e peut etre soit un ot pr d ni e e e (par exemple, cin), soit un chier. Il est alors possible de tester ce ot dentr e (dans lexemple on regarde si il e ` correspond a cin):
if (&in==&cin) ...;
chier input.dat :
4 2 4 1 3 2 4 3 1 5
chier output.dat
calcul de 2*x1+x2 : taille du vecteur : 4 coefficient du vecteur : 5 8 11 7
le nombre de colonnes; les coefcients sont g r s par un tableau de Vecteur ee (pointeur de Vecteur)
#ifndef MATRICE #define MATRICE #include "Vecteur.h" class Matrice { int nligne; int ncolonne; Vecteur * coefligne; public : Matrice (int=0, int=0); Matrice (const Matrice &); Matrice(); Matrice & operator= (const Matrice &); }
class Matrice { ... Matrice (const Vecteur &); ... } Matrice::Matrice (const Vecteur & v): nligne(v.taille),ncolonne(1) { coefligne = new Vecteur [nligne](ncolonne); for (int i=0; i<nligne; i++) coefligne[i][0] = v[i]; } main() { Vecteur v(10); cin >> v; Matrice m=v; cout << m; }
7. H ritage e
Concept fondamental de la POO
Une classe dite d riv e peut h riter dune classe (ou e e e plusieurs) : elle a donc implicitement les propri t s de ee celle-ci en plus de propri t s caract ristiques propres. ee e Exemple : classe point color e qui h rite dune classe e e point.
class Point { int x; int y; public : Point(int, int); void deplace(int, int); void affiche (); }; class Pointcol : public Point { char couleur; public : void colore (char cl) {couleur = cl;} };
Ici, Pointcol h rite de mani` re publique de Point. e e Donc les membres de Pointcol ont acc` s aux membres e publics de Point mais pas aux membres priv s e
Exemple :
void Pointcol::affichecol() { affiche();; //appel affiche de la classe m`re e cout << "couleur : " << couleur << endl; }
On peut aussi red nir la fonction affiche. Il faut alors e distinguer les deux m thodes du m me nom : celle de la e e classe m` re et celle de la classe d riv e. e e e
void Pointcol::affiche() { Point::affiche();; //appel affiche de Point cout << "couleur : " << couleur << endl; }
La cr ation dun objet Derive n cessite dabord la e e cr ation dun objet Base. Le constructeur de Base est e appel implicitement avant toute autre instruction au tout e d but de l xecution du constructeur de Derive. e e
On a le processus inverse pour le destructeur. Celui de la classe m` re est appel implicitement a la n de lex cution e e e ` de celui de la classe d riv e. e e
La description pr c dente est incompl` te comme expliqu e e e e ci-apr` s. e A la construction dun objet Pointcol, son constructeur est appel et ce dernier appelle alors imm diatement celui e e de Point qui attend 2 arguments.
Pour transmettre les arguments entre le constructeur de la classe d riv e et celui de la classe m` re, on d crit cette e e e e transmissions dans len-t te de Pointcal de la mani` re e e suivante :
class Pointcol : public Point { char couleur; public : void affiche() { cout << "position " << x << " et " << y << endl; cout << "couleur " << couleur << endl; } }
Ces m mes champs restent priv s pour les utilisateurs de e e la classe Point.
Amiti s et h ritage e e Les fonctions amies dune classe d riv es ont les m mes e e e autorisation dacc` s que les fonctions membres de cette e classe (notamment pour lacc` s aux membres prot g s). e e e Les d clarations damiti ne sh ritent pas. e e e
Voici les propri t s de ce type de d rivation : ee e Les membres publics de la classe de base sont accessibles partout.
Les membres prot g s de la classe de base sont accessibles e e aux fonctions membres et aux fonctions amies de la classe d riv e, mais pas aux utilisateurs de la classe d riv e. e e e e Les membres priv s de la classe de base sont inaccessibles e en dehors de cette classe de base.
` Elle interdit a un utilisateur dune classe d riv e lacc` s e e e aux membres publics de sa classe de base. Par contre, le concepteur de la classe d riv e peut utiliser les membres e e publics de la classe de base (comme un utilisateur ordinaire de la classe de base).
Par exemple, si Pointcol h rite de mani` re priv e, un e e e objet de type Pointcol ne pourra pas appeler deplace() qui est un membre public de Point.
Elle permet que les membres publics de la classe de base soient consid r s comme prot g s pour les d rivations ee e e e suivantes.
le constructeur de copie par d faut sera appel , e e pour la partie h rit e de A, le constructeur de copie de e e A sera appel sil existe (sinon cest encore le e constructeur de copie par d faut) e
Si B poss` de un constructeur de copie, e celui-ci sera appel ... mais pas celui de A. e Donc le constructeur de copie dune classe d riv e doit e e prendre en charge la totalit de la copie de lobjet et e notamment sa partie h rit e. Mais ... e e ... on peut utiliser un constructeur de A dans le ` constructeur de copie de B et lui transmettre lobjet a copier x lui-m me. Alors x est converti au type A avec e appel du constructeur de copie.
B(B &x) : A(x) //on provoque lappel //du constructeur de copie de A { //copie de la partie de x spcifique ` B} e a
` laffectation se fait membre a membre, la partie h rit e est g r e par laffectation e e ee eventuellement red nie dans A. e Si B a une d nition de = e Seule laffectation de B est appel e et pas celle de A. e Lop rateur = de B doit g rer tous les membres m me e e e ceux h rit s e e
126- G. Pr vost @ Universit du Havre e e
8. G n ricit et template e e e
` e La g n ricit consiste a d nir des fonctions et des classes o` e e e u les types sont param trables. e Plan 1. Fonctions g n riques e e 2. Patron de classe 3. Sp cialisation dun patron de classe e