Professional Documents
Culture Documents
M. AMEUR
Plan
Conception Objet
Introduction au C++
Classes
Hritage
Polymorphisme
et ++...
Bibliographie
Assignations
Fonctions
Contrle
Les variables
Pour dclarer une variable, on fait prcder son nom par son type.
Il existe 6 types de variables :
char caractre cod sur 1 octet
short entier cod sur 1 octet
int entier cod sur 4 octets
long entier cod sur 8 octets
float rel cod sur 4 octets
double rel cod sur 8 octets
On peut faire prcder chaque type par le prfixe unsigned, ce qui force les variables prendre
des valeurs uniquement positives.
Affichage sur l'cran
Fonction printf() de la bibliothque stdio.h
Saisie au clavier
La fonction getch() bibliothque conio.h
Saisie d'un caractre alphanumrique sans echo cran
else
{
/* code excuter si le test est faux*/
}
switch(variable)
{
case valeur1:
/* bloc 1*/
break;
case valeur2:
/* bloc 2*/
break;
default:
/* bloc_par_dfaut*/
break;
}
Les boucles
Il existe deux types de boucle:
La boucle for permet de runir la dclaration, la condition et
l'incrmentation.
int i;
La boucle while
int i = 0;
do {
while(i < 10)
{ /*instructions ... */
/* bloc rpter */
i++;
} } while (expression)
Les fonctions
Une fonction permet de renvoyer un rsultat en fonction des donnes passes
en paramtres. Pour dclarer une fonction, a prend la forme :
int carre(int nombre)
{
return nombre * nombre;
}
La dclaration doit tre faite avant l'appel de la fonction qui se fait comme ceci :
int retour = carre(2);
Utilisation:
nombre = &nb2 ; //Contenu de nombre = adresse de nb2
Comparaison de pointeurs :
Un pointeur ne pourra tre compar qu' un pointeur sur le mme
type (ou la constante NULL). Le rsultat de la comparaison
sera significatif et portable que si les pointeurs pointent sur le
mme objet.
Arithmtique des pointeurs
Exemples:
int *P;
Implmentation
Donnes Mthodes * Interface: dcrit ce que fait
l'objet
Pri
Priv Priv
v * Implmentation: dfinit
comment raliser l'interface.
Public Public Public
Interface
Concepts fondamentaux des objets
Identit et classification
Consiste regrouper les objets ayant le mme comportement pour
former un mme ensemble , appel: classe ( cd un nouveau type).
Un objet d'une classe s'appellera une instance de cette classe.
En C++ on dclare une classe par :
class Maclasse { ..........};
Hritage
Consiste dfinir une nouvelle classe partir d'une classe existante
laquelle on va ajouter de nouvelles proprits ( attributs et/ou
mthodes).
Concepts fondamentaux des objets
Polymorphisme
possibilit divers objets de classes drives d'une mme classe de
rpondre au mme message chacun sa faon. i.e un mme nom
peut dsigner des proprits de classes diffrentes.
Exemple: on peut invoquer la mthode ouvrir() quelque soit le type de
la porte automatique ou classique.
Gnricit
consiste dfinir des classes paramtres. Une classe gnrique n'est
pas directement utilisable, mais permet de crer des classes drives
qui peuvent tre manipules.
Modularisation
les modules sont construits autour des classes.
Concepts fondamentaux des objets
Un peu d'histoire
C++ se base essentiellement sur 2 langages:
Simula 67 (1967) cre pour le traitement des problmes de
simulation, dont il hrite le concept objet ( un programme
autonome actif pouvant communiquer et se synchroniser
avec d'autres objets) .
Langage C (1972) aux Bell Labs.
C++ versus C
C++ dispose d'un certain nombre de spcificits par rapport C en
dehors de l'orient objet:
Les commentaires
L'emplacement libre des dclarations des variables
Les arguments par dfaut
La surcharge (surdfinition) des fonctions
Les oprateurs new et delete
Les fonctions en ligne ( inline)
Les rfrences
...
Le Langage C++
La fonction principale
la fonction main() est le point d'entre de tout programme C++. Elle peut
tre dfinie de 2 manires:
Pour les programmes sans paramtres: int main() {....}
Pour les programmes avec paramtres:
int main( int argc, char* argv[]){...}
o argc: le nombre de paramtres
et argv[]: tableau de paramtres
Le Langage C++
Les commentaires
Sur plusieurs lignes: /* .............comme en C....
...............*/
Sur une seule ligne: //.... spcifique C++......
Le Langage C++
Les E/S
Entres/sorties fournies travers la librairie < iostream>
cout << expr1 << << exprn
Instruction affichant expr1 puis expr2, etc.
cout : flot de sortie associ la sortie standard (stdout)
<< : oprateur binaire associatif gauche, de premire oprande
cout et de 2me lexpression afficher, et de rsultat le flot de sortie
<< : oprateur surcharg (ou sur-dfini) utilis aussi bien pour les chanes de caractres,
que les entiers, les rels etc.
cin >> var1 >> >> varn
Instruction affectant aux variables var1, var2, etc. les valeurs lues au clavier.
cin : flot dentre associe lentre standard (stdin)
>> : oprateur similaire <<
Le Langage C++
E/S (2)
Possibilit de modifier la faon dont les lments sont lus ou crits dans le flot :
#include <iostream.h>
#include <iomanip.h> // attention a bien inclure cette librairie
int main() {
int i=1234;
float p=12.3456;
cout << "|" << setw(8) << setfill('*')
<< hex << i << "|" << endl << "|"
<< setw(6) << setprecision(4)
<< p <<''|'' << endl;
}
Le Langage C++
Les constantes
Le qualificatif const peut tre utilis pour une expression
constante:
const type_var var=cte;
Les rfrences
une rfrence sur une variable est un identificateur qui joue le rle d'un alias (pseudo)
de cette variable.
Syntaxe: type &nom_ref = var;
exemple:
int n;
int &rn=n; // rn est une rfrence de n
n=10;
cout<< rn; //affiche 10
Une rfrence ne peut tre vide, elle doit toujours tre initialise lors de sa
dclaration, i.e : int &rn ; // erreur!
Il est possible de rfrencer des valeurs numriques, dans ce cas il faut les dclarer
comme constantes, i.e: int &rn=3; // erreur!
const int &rn=3; // OK
Les rfrences et les pointeurs sont lis.
Le Langage C++
int fct(void); int fct();
Le Langage C++
Allocation dynamique
en C la manipulation dynamique de la mmoire se fait avec malloc et
free (<stdlib.h>). En C++, ces fonctions remplaces
avantageusement par les oprateurs unaire new et delete.
main()
...
delete pi;
delete [] tab;
}
Classes & objets
Exemple
class Point
{
private:
int x; Donnes membres ( ou attributs) privs
int y;
public:
void initialise(int,int);
void deplace(int,int); Mthodes public
void affiche();
} ;
x = abs;
y = ord;
}
Remarques:
Toutes les possibilits offertes par C++ pour les fonctions restent valables
pour les fonctions membres (surcharge, arguments par dfaut, ).
Toute fonction membre dfinie dans sa classe (dans la dclaration de la
classe) est considre par le compilateur comme une fonction inline. Le mot
cl inline n'est plus utilis.
Classes & objets
Point A;
Constructeur/Destructeur
C++ permet l'utilisation de fonctions membres dites constructeurs et
destructeur qui sont implicitement appeles respectivement lors de
la cration et la destruction d'un objet.
Exemple:
class Point {
int x;
int y;
public:
Point(int,int); // constructeur
~Point(); // destructeur Dans cet exemple, la dfinition du destructeur sera de la forme:
Point::~Point() { }
};
Classes & objets
Constructeur/Destructeur
Le destructeur est une fonction qui ne prend aucun argument et
ne renvoie aucune valeur.
En pratique les destructeurs sont utiliss pour librer
d'ventuels emplacements mmoire occupe par des membres
donnes.
Classes & objets
Exemple:
Considrons par exemple une classe Tab_entiers, qui permet de traiter des tableaux d'entiers dont les
dimensions sont fournies en donnes. Le constructeur aura donc la tche d'allouer dynamiquement
l'espace mmoire ncessaire pour l'instance crer et le destructeur doit librer cette zone.
Exercice:
1) On dsire munir la classe Point d'un constructeur qui permet de crer le
point :
(0,0) si aucun argument n'est fourni
Attribut statique
Un membre donne dclar avec l'attribut static est une donne
partage par toutes les instances d'une classe.
Un membre donne statique est initialis par dfaut zro. Mais :
Il doit tre dfini l'extrieur de la dclaration de la classe, mme s'il est priv, en
utilisant l'oprateur de port (::).
Exemple:
class cpt_obj
int a;
public:
cpt_obj(int); // constructeur
};
cpt_obj::cpt_obj(int n) {
a = n;
cpt_obj++;
}
Classes & objets
Exemple:
Classes & objets
Exemple:
#ifndef, #define et #endif sont ajouts aux fichiers include pour que le
fichier ne soit inclus quune seule fois lors dune compilation.
Enfin, dans tout programme utilisant la classe nom_classe, on doit
inclure le fichier d'entte ''nom_classe.h''. Un tel programme doit
aussi pouvoir accder au module objet rsultant de la compilation du
fichier source contenant la dfinition de la classe.
Classes & objets
Exemple:
Dfinir une fonction qui permet de comparer deux instances de la classe
Point. Cette fonction devra retourner "true" si les deux objets
concident et "false" sinon.
Et sa dfinition:
bool Point::coincide(Point pt)
}
Classes & objets
Exemple:
On dsire dfinir la fonction symetrique() qui permet de retourner le symtrique
d'un point de la classe Point.
Cette fonction doit tre une fonction membre de la classe Point, puisqu'elle doit
accder aux coordonnes du point, qui sont des donnes prives. La valeur
de retour sera de type Point La dclaration de la fonction dans la classe sera
:
Point symetrique();
et sa dfinition
Point Point::symetrique()
Point pt;
Return pt; Question: Peut-on transformer cette fonction pour qu'elle fournisse un pointeur
(ou une rfrence) du rsultat ?
} Non, puisque le calcul du rsultat doit se faire sur une variable locale la fonction.
Classes & objets
Le pointeur this
En C++, tous les objets possdent un champ priv particulier nomm this, sans quil
soit ncessaire de le dclarer. Ce champ contient ladresse de lobjet courant.
Dans une fonction membre, this reprsente un pointeur sur l'instance ayant
appel cette fonction
this est un pointeur constant, c'est--dire qu'on ne peut le modifier.
Exemple:
class Point { point::point(int abs, int ord) { x = abs; y = ord;}
int x; int y; void point point::affiche()
{
public: cout << " le point : (" <<this x << "," << this y << ")" ;
cout << " est l'adresse " << this << endl;
point(int=0, int=0); }
void affiche();
};
Classes & objets
Les membres de classe, sont aussi dits membres statiques. Ils sont
dclars avec l'attribut static, et existent mme si aucun objet de la
classe n'est cre.
Ainsi on peut dfinir un membre donne statique comme on peut
dfinir une fonction membre statique. L'accs ces membres se fait
avec l'oprateur de rsolution de porte (::) prcd par le nom de la
classe ou d'un quelconque objet de la classe
Classes & objets
Exemple:
// Interface de la classe : POINT.H // Corps de la classe : POINT.CPP
#include "Point.h"
#ifndef POINT_H // definition obligatoire du membre donn statique
#define POINT_H int point::nb_obj;
Point::Point(int abs, int ord)
#include <iostream.h> // utilis dans affiche() {
x = abs; y = ord;
class Point{ nb_obj++;
}
int x; Point::~Point()
{
int y;
nb_obj--;
static int nb_obj; }
void Point::affiche()
public: {
cout << "(" << x << "," << y << ")" << endl;
Point(int = 0, int = 0); }
// definition de la fonction membre static
~Point(); void Point::affiche_nbobj()
void affiche(); {
cout<<''le nombre d'objets est''<<nb_obj<<endl;
static void affiche_nbobj(); }
----
};
#endif
Classes & objets
Exemple (suite)
// Programme test
#include "Point.h"
void main()
Point::affiche_nbobj();
Point A;
A.affiche_nbobj();
Point B(5,6);
Point::affiche_nbobj();
}
Classes & objets
}; T w;
u.K(v); //OK
u.K(w); // OK
v.K(w); // erreur:instance constante et fct non constante
Remarque: Une mthode constante peut tre appele sur un objet variable
ou constant.
Classes & objets
On adoptera donc la discipline de programmation suivante :
. mthode daccs aux donnes ou accesseur : il sagit des
mthodes qui retournent ou affichent des donnes de lobjet sans les
modifier. Les accesseurs doivent tre des mthodes constantes.
. mthode de modification des donnes ou modificateur ou
mutateur : il sagit des mthodes qui modifient les donnes de
lobjet. Un modificateur ne doit donc pas tre appel sur un objet
constant. Par consquent, un modificateur ne doit surtout pas tre
dclar comme mthode constante.
Classes & objets
Dclaration et initialisation des objets
Les objets suivent les mmes rgles que les variables ordinaires, nous
distinguerons alors :
Les objets globaux : ceux qui sont dclars en dehors de tout bloc.
Les objets automatiques : ceux qui sont dclars au sein d'un bloc
Les objets statiques : ce sont les objets locaux statique (dfinie avec le
mot cl static)
Classes & objets
Cas d'une classe sans constructeur
Les donnes membres des objets globaux et statiques, qui ne sont pas
des pointeurs, seront initialiss par dfaut 0.
L'initialisation explicite des objets lors d'une dclaration ne peut se faire
qu'avec des objets de mme type, comme par exemple :
T a;
T b = a;
o T est une classe. Dans ce cas, le compilateur fera une copie simple
des valeurs des membres donnes de a dans ceux de b.
Notez que, l'utilisation d'une classe sans constructeur et comportant un
pointeur est fortement dconseille, du fait qu'aucune initialisation
implicite ne sera parfaite et que lors de l'initialisation d'un objet par un
autre, les deux objets concerns partageront la mme zone mmoire
pointe par le pointeur
Classes & objets
Cas d'une classe avec constructeur
Pour une telle classe, toute dclaration doit comporter une initialisation.
Ainsi, pour dclarer par exemple un objet u d'une classe T, on doit
utiliser l'une des syntaxes suivantes :
syntaxe 1: T u=v;
syntaxe 2: T u(liste_des_valeur);
syntaxe 3: T u = T(liste_des_valeur);
Dans syntaxe 1, v est un objet de la classe T (dfini antrieurement).
Les syntaxes 2 et 3 sont quivalentes. Dans ces deux formes,
liste_des_valeur est une liste de valeurs qui correspond la liste des
arguments du constructeur, en tenant compte des valeurs par dfaut
dfinies par le constructeur et des surcharges ventuelles du
constructeur (autrement dit, T(liste_des_valeurs) doit tre un appel
valable de la fonction membre T)
Classes & objets
Exemple:
class T {
int i;char c;
public:
T(int n, char cc = 'a' ){i=n; c=cc;}
};
T a(5,'A'); // ou T a=T(5,'A')
T b = T(3); // ou T b(3) et quivalent T b(3,'a')
T c = a;
Classes & objets
Cas d'une classe avec constructeur (suite)
T(float x =0.0){z=x;}
};
//La dclaration
Il y aura une copie simple des valeurs des membres donnes de v dans
ceux de u. Par suite, les pointeurs u.adr et v.adr dsigneront la
mme adresse, ce qui posera deux problmes :
Toute modification contenu de *adr de l'un des objets se fera aussi
pour l'autre.
La destruction de l'un des objets, entranera la destruction du pointeur
du deuxime.
Classes & objets
Exemple
#include <iostream.h> // --------------- Dfinition des fonctions membres
T::T(int n, int p)
//------------ Dclaration de la classe {
i = n;
class T{ pi = new int;
*pi = p;
int i; }
int *pi; T::~T()
{
public: if(pi != NULL)
delete pi;
T( int = 0, int = 0); }
void T::affiche()
~T(); {
cout << "(" << i << "," << *pi << ") --> " << pi <<
void affiche();
endl;
void modifier(int,int); }
void T::modifier(int n, int p)
}; {
i = n ; *pi = p;
}
Classes & objets
Exemple (suite)
// ----------------------------------------- Test
void main()
T u;
T v = u;
// on modifie v
v.modifier(2,2);
}
Classes & objets
Constructeur par recopie (suite)
Pour rsoudre ce type de problmes, C++ offre la possibilit de dfinir un
constructeur particulier appropri ce genre de situation. Ce constructeur est
appel constructeur par recopie (copy constructor) et il est dclar comme suit:
T ( T &);
et on refait le mme test que dans l'exemple prcdent, pour montrer que les
problmes poss par l'initialisation d'un objet par un autre sont bien rsolus.
Classes & objets
Tableau d'objets
En thorie, un tableau peut possder des lments de n'importe quel
type. Ainsi nous pouvons dclarer un tableau de N objets d'une classe T
par :
T tab[N];
Or, du fait qu'on ne peu dclarer un objet sans l'initialiser, cette dclaration ne
sera possible que si la classe T admet un constructeur sans arguments (ou
un constructeur dont tous les arguments ont des valeurs par dfaut).
Ces mmes remarques s'appliquent pour les tableaux dynamiques d'objets.
Une dclaration de type :
T * adr = new T[N];
ncessite aussi un constructeur sans arguments.
Classes & objets
Objet d'objets
Une classe peut comporter un membre donne de type classe.
Considrons alors la situation suivante, o la classe T comporte un
membre donne de type classe A :
class A{
public:
A(liste_arguments_a);
};
class T{
A a;
public:
T(liste_arguments);
Classes & objets
Objet d'objets (suite)
Lors de la cration d'un objet de type T, il y aura appel du constructeur de T puis un appel
du constructeur de A, car la cration d'un objet ncessite la dfinition de tous les
membres donnes de l'objet (en particulier le membre a de type A).
Par suite, la cration d'un objet de type T ne sera possible que si A possde un
constructeur sans arguments.
...
f r i e n d c l a s s C2 ;
...
};
Classes & objets
'Friend' en rsum
Les amis dune classe sont des classes ou des fonctions
Les amis dune classe peuvent accder toutes les mthodes
et donnes membre de la classe quel que soit le niveau de
protection
Les amis dune classe sont dfinis lintrieur de la classe
Violation parfois utile, mais trs souvent dconseille du
principe d'encapsulation
Classes & objets
La surcharge des oprateurs
En C++, les oprateurs dfinis pour les types de base sont traits par le
compilateur comme des fonctions, ce qui permet donc, avec la
technique de la surcharge, d'utiliser la plus part d'entre eux avec les
types classe
Les oprateurs redfinissables sont :
Syntaxe gnrale :
type_de_retour operator op(liste arg);
Exemple :
class Point {int x,y; };
Prototype de la fonction amie operator + :
Point operator +(Point,Point) ;
Pas de paramtre
Dfinition :
class Point
{
public:
operator double(); // oprateur unaire
private:
int x,y ;
};
Implmentation :
Point::operator double()
{
return sqrt(x*x+y*y) ;
}
Utilisation :
main()
{
Point pt(10,3) ;
double f ;
f = (double)pt ; // ou double (pt) ;
}
HERITAGE
A l'origine
Pourquoi?
recopier est peu valorisant
recopier est coteux en dveloppement (criture,
mise au point, tests)
recopier est coteux en maintenance
(multiplication des erreurs)
HERITAGE
L'ide
L'ide (suite)
La relation d'hritage:
est_un
possde les caractristiques de
HERITAGE
Le principe (suite)
Vhicule
Vhicule
Hritage simple :
Hritage multiple :
Exemple
class D
{public :
D(int,int) ;
};
class E : public D // E drive de D
{public :
E(int,int,int) ;
};
// initialisation de la classe de base
E::E(int x,int y,int z) : D(x,y)
{
}
HERITAGE
Constructeurs
CAS 1 : Cas o le constructeur de la classe drive est synthtis par le
compilateur (sans paramtres) : ce constructeur appelle le constructeur par
dfaut de la classe de base (appel sans argument du constructeur synthtis
ou d'un constructeur dfini sans paramtres ou dont tous les paramtres ont
une valeur par dfaut)
class A class A
class A { {
{ private: private:
private: public: public:
public: A(); A(T1 a1, T2 a2);
}; }; };
class B : public A
{
private:
public:
B(T1 b1, T2 b2, T3 b3);
};
Syntaxe :
class MaClass : private MaClasse_de_Base
{
...
};
Quand lutiliser ?
Toutes les fonctions utiles de la classe de
base sont redfinies dans la classe
drive et on ne veut pas laisser
lutilisateur du programme accder aux
fonctions de la classe de base
(exemple : Pile drive de Tableau)
HERITAGE
Hritage priv (suite)
Ce type d'hritage s'utilise lorsque la classe drive n'est pas un cas particulier
Exemple: de la classe de base (bien que sa dfinition s'appuie sur celle de la classe de
base).
class Table class Pile : private Table
{ {
int nb; double *sommet;
double *tab; public:
public: Pile();
Table(); Pile(int taille);
Table(int taille); void empiler(double x);
Table(const Table&); double depile();
~Table(); bool isEmpty();
Table& operator=(const Table&); };
double& operator[](int);
};
L'implmentation de Pile s'appuie sur celle de Table, mais il est ncessaire de cacher l'utilisateur la
possibilit d'accder n'importe quel lment de la pile par l'oprateur []; pour cette raison on choisit
lhritage priv.
HERITAGE
Rtablissement des droits d'accs
Il est possible de rtablir les droits d'accs modifis par la drivation pour
rtablir les droits d'origine de ces attributs ou mthodes.
Le rtablissement ne concerne que les membres dclars public ou
protected dans la classe de base.
class A
class B : private A int main()
{
{ {
public: public: B b;
using A::a1; b.a1 = 1; // OK
int a1; }; b.a2 = 1; // Illgal
int a2; return 0;
};
};
HERITAGE
Le polymorphisme :
dans le prolongement de la surdfinition et de la
redfinition.
Surdfinitionou surcharge (overloading): les fonctions ont le mme
nom, mais le compilateur les distingue par la liste de paramtres
Redfinition (overriding): les fonctions membre ont exactement le mme
en-tte (nom et paramtres identiques), mais le compilateur les distingue selon le
type dclar de l'objet auquel on les applique
Polymorphisme: les fonctions membre ont toujours le mme en-tte, mais le
compilateur gnre, pour celles qui sont dclares virtuelles , des instructions
supplmentaires qui permettent de les distinguer lors de l'excution selon le type
effectif de l'objet auquel on les applique, tout ceci dans les limites d'une mme
hirarchie d'hritage
METHODE VIRTUELLE
SYNTAXE DE DECLARATION
class A
{
public:
A() {} ;
virtual bool IsA() const ;
};
class B : public A
{
public:
B() {} ;
virtual bool IsA() const ;
// virtual est optionnel dans la classe drive
};
METHODE VIRTUELLE
SYNTAXE DIMPLEMENTATION
bool A::IsA() const
{
return TRUE ;
}
A* pA = new A ;
A* pB = new B ;
if (pA->IsA())
cout << "Objet de classe A ";
if (pB->IsA())
cout << " Objet de classe A ";
delete pA ;
delete pB ; // ERREUR !!!!
// Destructeur de B non appel
Rappel :
En POO, on considre quun objet dune classe drive peut remplacer un
objet de la classe de base
Mthodes virtuelles
Remarque:Toujours dclarer virtuel le destructeur dune classe de
base destine tre drive pour sassurer d' une libration complte
de la mmoire.
SYNTAXE DE DECLARATION
class X
{
// Dfinition dune fonction virtuelle pure
// =0 signifie quelle na pas de dfinition
// Attention, cest diffrent dun corps vide : { }
Une classe abstraite est une classe qui contient au moins une
mthode virtuelle pure
is tre a m o s tre a m
iostream
fstream
Les entres-sorties
Classe OSTREAM
cout est un objet de la classe ostream
#include <iostream.h>
ou
#include <iostream>
using namespace std ;
oprateur << surcharg pour les types de base
char ch[20] ;
int len ;
while (cin.getline(ch,20))
{ len = cin.gcount() ;
}
istream & read(char * t,int x);
// lecture de x bytes
char t[5] ;
cin.read(t,5) ;
Les entres-sorties
Connexion d'un flot un fichier
#include <iostream.h>
#include <fstream.h>
Ecriture dans un fichier :
crer un objet de la classe ofstream (drive de ostream)
ofstream fic_out ("fic",ios::out) ;
fic.close() ;
Les entres-sorties
Exemple
Louverture dun fichier est ralis laide de la mthode open
commune aux 3 classes,
#include <fstream.h>
int main( void )
{
ifstream f1; // instanciation de lobjet
f1.open("essai1.tmp"); // ouverture du flux de donnes
ofstream f2("essai2.tmp"); // combinaison des oprations
// ... ... ... ... ...
}
Les entres-sorties
Exemple complet
But lire et crire 1, 2, 3 dans un fichier!
#include <fstream>
osf.close(); }
{ int x, y ;
public :
};
Les entres-sorties
// Redfinition de loprateur << en fonction amie de la classe Point
{ sortie << "(" << p.x << "," << p.y << ")" ; return sortie ; }
istream & operator >> (istream & entree, point & p) // Si la saisie a t correcte, on affecte p
}
Les entres-sorties
int main()
{
point b
cout << "donnez un point : " ;
if (cin >> b)
cout << "Affichage du point : " << b << endl ;
else cout << "** information incorrecte" << endl ;
}
Patrons (Templates)
Patrons de fonctions
template <typename T> T min (T a, T b)
{
if (a < b) return a; Paramtre de type T
else return b ; (T = type quelconque)
} typename T ou class T
min (3,7) ;
min(5.6,9.8) ;
main()
{
Point p1(2,5), p2(1,8),p3 ;
p3 = min(p1,p2) ;
}
Patrons (Templates)
Patron de fonction: paramtres de type
a=x+y+z;
return a ; }
Patrons (Templates)
Les patrons de classes
Exemple :
Tableau <int,4> t1 ;
Tableau <float,100> t2 ;
La gestion des exceptions
Le principe de la gestion des exceptions par C++ est le suivant :
quand une fonction veut signaler une erreur, elle lance (throw) un objet
erreur ;
lorsque l'utilisateur veut grer l'erreur, il attrape (catch) l'objet lanc ;
une erreur non attrape conduit un arrt du programme.
Cette technique est suprieure celle du renvoi de codes d'erreurs :
elle n'accapare pas la valeur de retour des fonctions ;
elle ne fait pas intervenir de variables globales ;
elle ne ncessite pas de paramtres supplmentaires, l'objet erreur pouvant
vhiculer des informations aussi complexes qu'on le souhaite ;
elle peut signaler une erreur dans un constructeur ou un destructeur (qui n'ont
pas de valeur de retour).
La gestion des exceptions
On lve une exception par l'instruction throw suivie d'une expression
quelconque (entier, double, chane de caractres, objet, ...).
Fichier MonException.h
class MonException {
public:
char *msg1, *msg2;
MonException (char *s1, char *s2);
};
int main()
{
try
{
// Demander a l'utilisateur d'entrer
void ouvrir(char* name) // un nom de fichier
{ ouvrir(filename);
FILE *f; // Utiliser le fichier ouvert pour
f = fopen(name, "r"); // lire des donnes
}
throw(1); catch (int n)
} {
if (n == 1)
std::cerr << "PB de fichier\n";
}
La gestion des exceptions
Interception des exceptions
A chaque type qui peut tre utilis pour lancer une exception, il faut prvoir un
gestionnaire (catch) adapt (si on veut attraper lexception, bien sr) :
void ouvrir(char* name)
FILE *f;
FILE *f;
try {
f = fopen(name, "r"); ouvrir("input.txt");
}
if(f==NULL) catch (MonException &e) {
std::cerr << e.msg1<< e.msg2;
throw MonException("Probleme avec",name); }
La gestion des exceptions
Interception des exception
S'il n'y a pas de gestionnaire de type compatible associ au bloc try, l'exception
n'est pas traite dans le bloc try, elle remonte de fonction appelante en fonction
appelante jusqu' trouver un gestionnaire compatible :
int main()
{
try
{
lire_donnees(); void lire_donnees()
... {
} try
catch(const char *s) {
{ ouvrir("in.txt"); void ouvrir(char* name)
std::cerr << s; ... {
} } ...
return 0; catch (int n) throw("Pb de fichier");
} { }
// fait quelque chose
}}
La gestion des exceptions
Interception des exceptions
La leve d'une exception s'apparente un branchement (goto). Les
instructions non excutes :
dans la fonction qui a lanc l'exception,
dans les fonctions rencontres lors de la remonte de la pile d'appels,
dans le bloc try qui a captur l'exception ,
... sont abandonnes.
Les variables locales ces fonctions sont dtruites (leurs destructeurs
sont appels).
La gestion des exceptions
Interception des exceptions
Un bloc try peut tre suivi de plusieurs gestionnaires catch. Dans ce cas,
ces gestionnaires sont essays squentiellement suivant l'ordre de leur
dfinition, et ce sera le premier compatible qui sera excut.
int main() {
try {
...
}
catch (const char *s) { std::cerr << s;}
catch (int n) { if (n==1) std::cerr << "PB de fichier";}
catch (MonException &e) { std::cerr << e.msg1 << e.msg2;}
return 0;
}
La gestion des exceptions
Interception des exceptions
Il existe un gestionnaire particulier, catch(...) qui attrape tout type d'exception.
Ce gestionnaire ne peut se trouver qu'en dernire position (sinon, les
gestionnaires placs derrire lui n'attraperaient jamais rien).
int main() {
try {
...
return 0;
}
La gestion des exceptions
Utiliser les exceptions pour corriger
// Soit une classe Table(Y,X),
// avec une mthode de calcul :
double Table::interpole(double x) Les exceptions servent afficher des
{ messages d'erreur explicites :
// S'il y a sortie de table par
// excs on lve une exception
// avec le nom de la table, les catch (TableError &e)
{
// valeurs limites et la valeur
// qui dpasse : std::cerr<< "Sortie dans table : " << e.name<< "La
valeur " << e.x<< " dpasse la limite " << e.max_x;
throw TableError(name, max_y, max_x,
}
x);
}
Les exceptions ne sont pas seulement un bon moyen pour savoir quelle partie
du code a produit une erreur et pourquoi, elles permettent aussi de corriger
ces erreurs et de permettre au programme de continuer.
La gestion des exceptions
Utiliser les exceptions pour corriger
Voici un exemple de correction applique dans le cas dune sortie de table
dinterpolation. On dcide daccorder 5% de tolrance, mais au del, on lve
nouveau une exception :
try
{
coeffAxial = tabCoeffAxial.interpole(machNumber);
}
catch (TableError &e)
{
if (e.x < (1.05*e.max_x))
coeffAxial = e.max_y;
else
{
std::cerr << "Sortie de table " << e.name
<< " au dela des tolerances " << std::endl;
throw(e);
}
}
La gestion des exceptions
Spcifier l'exception
Il est possible de spcifier les exceptions quune fonction ou une mthode a le
droit de lever :
class X {};
class A {
};
void g1();
int main ()
{ cout << "exception cration vect avec un mauvaise nombre d'lments " << endl ;
exit (-1) ;
}}
exception cration vect avec un mauvais
nombre d'lments
{ public :
private :
char ad_texte ;
};
La gestion des exceptions
int main()
{ try
{ cout << "bloc try 1" << endl;
throw mon_exception ("premier type") ; //construction la vole
}
catch (exception & e)
{ cout << "exception : " << e.what() << endl; }
try
Rsultat:
{ cout << "bloc try 2" << endl;
bloc try 1
throw mon_exception ("deuxieme type") ; exception : premier type
bloc try 2
} exception : deuxieme type
catch (exception & e)
{ cout << "exception : " << e.what() << endl;
}
}
La gestion des exceptions
Exceptions et constructeurs
Il est parfaitement lgal de lancer une exception dans un constructeur,
ce qui permettra de signaler une erreur lors de la construction dun
objet.
Lorsquune exception est lance partir dun constructeur, la
construction de lobjet choue. Par suite, le destructeur pour cet objet
ne sera pas appel, ce qui pose certains problmes si l'objet est
partiellement initialis.
La gestion des exceptions
Exemple:
L'exemple suivant montre comment traiter le cas des objets partiellement
initialiss, lorsque la cration de ces objets choue.
Considrons une classe "etudiant" qui permet de manipuler les notes d'un
tudiant.
Les notes de chaque tudiant seront stockes dans des tableaux d'entiers. On
suppose que le nombre de notes est variable et qu'il ne doit pas dpasser
une certaine valeur MAXNBNOTE.
On prvoit aussi dans cette classe une surcharge de l'oprateur [] qui permet
l'accs en lecture et en criture une note donne
Pour grer les diffrentes erreurs, on dfinit une classe de base "Erreur" et
deux autres classes DepMaxNbNote et InvalideIndice pour grer
respectivement le dpassement de nombre de notes autoris et le
dpassement d'indice.
La gestion des exceptions
#include <iostream>
#include <string>
#define MAXNBNOTE 4
public:
class InvalideIndice:public erreur{
erreur():raison(0){} public:
erreur(const char* s):raison(s){} InvalideIndice():erreur(){}
InvalideIndice(const char *s):erreur(s){}
virtual void affiche(){ void affiche(int i){
erreur::affiche();
if (raison == NULL) cout << "Indice doit etre entre 0 et " << i << endl;
cout << "Erreur inconnu..." << endl; }
};
else cout << raison << endl;
} };
La gestion des exceptions
//--------- classe etudiant //------------ constructeur
etudiant::etudiant(char* nom, int nbnotes)
class etudiant{ {
try
char * _nom; // nom
{
int _nbnotes; // nombre de notes _nom = new char[strlen(nom)+1];
strcpy(_nom,nom);
int * tabnotes; // tableau de notes if( (nbnotes < 0) || (nbnotes > MAXNBNOTE) ){
DepMaxNbNote err("Erreur dans Constructeur");
public: throw err;
}
etudiant(char*,int); _nbnotes = nbnotes;
~etudiant(); tabnotes = new int[nbnotes];
}
int GetNbNotes(){ return _nbnotes;} catch(DepMaxNbNote & err)
{
int & operator[](int); delete _nom;
err.affiche();
void affiche(); exit(-1);
}
};
}
La STL (standard template library)
La STL fournit entre autre:
des classes pour les structures de donnes classiques
structures squentielles : vector, list,
structures associative : (multi)set, (multi)map
des itrateurs offrant une interface uniforme pour manipuler ces
structures
des algorithmes varis sur ces structures
Il y a 3 types d'itrateurs :
unidirectionnel
bidirectionnel (--)
accs direct (it + i, it[i])
Remarque:
Itrateur de fin pointe juste aprs le dernier lment du conteneur
Si la liste vide : li.begin() possde la mme valeur que li.end()
La STL (standard template library)
Les algorithmes
Les algorithmes sont des fonctions C++ gnriques qui permettent
deffectuer des oprations sur les containers.
Afin de pouvoir sappliquer plusieurs types de containers, les
algorithmes ne prennent pas de containers en arguments, mais des
itrateurs qui permettent de dsigner une partie ou tout un container.
De ce fait, il est mme possible dutiliser ces algorithmes sur des
objets qui ne sont pas des containers.
Certains algorithmes ne ncessitent que des itrateurs de base
(dentre ou de sortie), et dautres ncessitent des itrateurs plus
volus, comme la fonction sort (effectuant un tri) qui ncessite un
itrateur accs direct.
La STL (standard template library)
Exemple
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
vector<int> tableauEntiers; // Cre un tableau dentiers vide
int unEntier;
// Saisie des entiers
// Tri du tableau
sort(tableauEntiers.begin(), tableauEntiers.end());
// Affichage des lments tris
vector<int>::iterator it;
for (it = tableauEntiers.begin(); it != tableauEntiers.end(); it++)
cout << *it ;
}