Académique Documents
Professionnel Documents
Culture Documents
Introduction
C++
Laurent Henocque
Matre de Confrences
Cours de programmation
Laurent Henocque
Le langage C++
Cours de programmation
Introduction C++
Utilisation avance du langage
Manuel de rfrence sommaire
ESIL / ES2I
Universit de la Mditerrane
par Laurent Henocque
(henocque@esil.univ-mrs.fr)
(http://www.esil.univ-mrs.fr/Staff/Prof/henocque/)
Ce document peut tre librement reproduit dans son intgralit pourvu que la prsente mention de copyright ainsi que
celles prsentes en tte et en pied de page y restent attaches. Toute autre forme de copie est interdite.
Auteur Laurent Henocque, matre de confrences.
Ce document est un cours de l
Ecole Suprieure dIngnieurs de Luminy,
dpartement Etudes Suprieures en Ingnierie Informatique,
163 Avenue de Luminy, case 925, 13288 Marseille Cedex 9
(http://www.esil.univ-mrs.fr)
0.
Introduction et plan
Cours de programmation
Laurent Henocque
Le langage C++
Ce cours voque les notions fondamentales du langages C++ telles quexposes dans louvrage C++ Seconde Edition,
par lauteur du langage C++ : Bjarne Stroustrup. Ce livre constitue un document de rfrence irremplaable. Nous en
reprenons ici de nombreux exemples, et une partie de la structure.
Lobjectif du cours est de servir de rfrence pour ltudiant soucieux dexploiter le plus possible les qualits du langage,
et envisage donc les diffrentes constructions dans un assez grand dtail.
Voici le plan de ce cours :
1.
A LA DECOUVERTE DEC++ 1
2.
1.1.
introduction1
1.2.
paradigmes de programmation
1
1.3.
"Un meilleur C"
4
1.4.
C++ apporte un support pour les abstractions de donn
es
6
1.5.
C++ apporte un support pour la programmation par objets 9
FONCTIONS ET FICHIERS
12
3.
2.1.
introduction12
2.2.
porte d'dition
12
2.3.
porte d'dition 12
2.4.
fichiers d' en tte .h
13
2.5.
ditions de liens avec du code non C++
2.6.
comment construire les bibliothques15
2.7.
les fonctions 15
2.8.
macros
21
2.9.
macros 21
2.10.
exercices
24
CLASSES 26
4.
3.1.
classes et membres 26
3.2.
interfaces et mise en oeuvre 29
3.3.
autres caractristiques des classes
3.4.
construction et destruction 34
3.5.
exercices
36
3.6.
37
HERITAGE 38
5.
4.1.
introduction et tour d'horizon
4.2.
hritage : classes drives 38
4.3.
classes abstraites
38
4.4.
hritage multiple
39
4.5.
hritage virtuel
39
4.6.
contrle d'accs
39
4.7.
mmoire dynamique39
DECLARATIONS ET CONSTANTES
41
5.1.
5.2.
5.3.
5.4.
14
30
38
dclarations 41
les noms
43
les types
43
les littraux 50
Cours de programmation
Laurent Henocque
Le langage C++
6.
5.5.
les constantes nommes
51
5.6.
les champs de bits et unions 53
5.7.
exercices
54
EXPRESSIONS ET INSTRUCTIONS
56
7.
6.1.
sommaire des oprateurs
56
6.2.
les instructions
65
6.3.
commentaires et indentation 67
6.4.
exercices
67
SURCHARGE D'OPERATEUR
70
8.
7.1.
introduction70
7.2.
fonctions oprateurs 70
7.3.
conversions de types dfinis par le programmeur
7.4.
littraux
73
7.5.
gros objets 73
7.6.
affectation et initialisation 73
7.7.
indexation 73
7.8.
oprateur dappel de fonction
73
7.9.
indirections 73
7.10.
incrmentation et dcrmentation 74
7.11.
une classe chane de caractres
74
7.12.
amies et membres 75
7.13.
avertissement
76
TEMPLATES 77
9.
8.1.
introduction77
8.2.
un patron simple : patron de classe 77
8.3.
listes gnriques
77
8.4.
fonctions gnriques globales81
8.5.
rsolution de la surcharge des fonctions gnriques 82
8.6.
arguments de template
82
8.7.
drivation et templates
83
8.8.
un tableau associatif 83
GESTION DES EXCEPTIONS
85
10.
9.1.
9.2.
9.3.
9.4.
9.5.
9.6.
9.7.
9.8.
FLOTS
10.1.
10.2.
introduction91
sorties
91
71
85
Cours de programmation
11.
Laurent Henocque
10.3.
entres
91
10.4.
mise en forme
93
10.5.
fichiers et flots
98
10.6.
entres/sorties C
99
NOTES RAPIDES AU PROGRAMMEURC
11.1.
11.2.
Le langage C++
100
Cours de programmation
1.
Laurent Henocque
Le langage C++
A la dcouverte de C++
1.1. introduction
C++ est une tentative d'amliorer C
C++ supporte labstraction de donnes
C++ permet la programmation objet
avantages : l'utilisateur ne connat que les fonctions, et la reprsentation interne peut changer
C++ supporte ce type de programmation par compatibilit avec C, et l'tend grce aux classes
Cours de programmation
Laurent Henocque
Le langage C++
les types ainsi conus par des classessont diffrents des types pr dfinisdans leur utilisation
le compilateur (C) reste incapable de dtecter certaines erreurs. Dans l'exemple ci dessous, s2 est utilis et dtruit sans
avoir t initialis.
main(){
stack_id s1,s2;
s1 = create_stack();
push (s1,'a');
char c = pop(s1);
push (s2,'b');
delete_stack(s2);
}
};
complex operator+(complex c1, complex c2){
return complex(a1.re+a2.re,a1.im+a2.im);
}
void main(){
complex a = 2.3;
Cours de programmation
Laurent Henocque
Le langage C++
complex b = 1/a;
complex c = a+b*complex(5,7.3);
c = c-a*b+2;
}
Dans l'exemple ci dessus, les fonctions de construction de la classe "complex" sont appeles automatiquement, et la
dfinition des oprateurs pour ce nouveau type permet de l'utiliser "comme" un type prdfini. C'est du C++.
};
void shape::draw(){
switch (type){
case circle : break;
case triangle : break;
case square : break;
}
}
dans l'exemple ci dessus, chaque nouvelle forme ajoute impose de toucher le code de toutes les fonctions importantes
dfinies pour le type "forme"
Cours de programmation
Laurent Henocque
Le langage C++
class shape {
point center;
public:
point where () { return center;}
void
les fonctions dont l'interface d'appel peut tre dclare, mais ne peut pas tre dfinie, ont t dclares
virtual
de telles fonctions sont dites constituer le protocole de la classe abstraite shape.
une fonction virtuelle est lie dynamiquement : la bonne fonction est appele automatiquement sur un objet, mme
quand son type exact est inconnu
shape *tab[50];
void draw_all(float){
for (int i=0; i<50;i++){ tab[i]->rotate();}
}
Cours de programmation
Laurent Henocque
Le langage C++
Cours de programmation
Laurent Henocque
Le langage C++
// ok
p=&v[3];
1.3.7. fonctions
les types des arguments sont contrls lors de l'appel et ventuellement convertis
dans le type attendu
la signature d'une fonction (on dit aussi son "prototype") est constitue de :
son nom
les types de ses arguments dans l'ordre ou ils se prsentent
le type retourn par la fonction n'est pas indiffrent, mais n'est pas traditionnellement en C++ considr dans sa
signature.
deux fonctions diffrentes peuvent porter le mme nom : int f(int); int f(float). On parle alors de surcharge, ou de
polymorphisme. Le compilateur a l'intelligence de savoir quelle fonction appeler en fonction des types des arguments qui
sont proposs.
le passage d'argument par rfrence est possible comme en Pascal (passage VAR). En C, le mme mcanisme requiert
l'utilisation explicite de pointeurs.
void swap (int& i, int&j){ // permute les valeurs de deux variables
int aux = j;
j = i;
i = aux;
}
int main (){
int a = 1;
int b = 2;
cout << a << " " << b << endl;
swap(a,b);
cout << a << " " << b << endl;
return 0;
Cours de programmation
Laurent Henocque
Le langage C++
condition
d'informer
extern permet de spcifier le type de convention de passage des arguments (fortran et pascal sont comme "C")
on peut rpartir la programmation dans des fichiers spars avec rfrences externes
// header.h
extern char *chaine;
// chainedef.cc
#include "header.h"
char *chaine = "hello world\n";
//chainedisp.cc
#include "header.h"
#include <iostream.h>
main(){
cout << chaine;
return 0;
}
//compilation
ou encore:
CC -c chainedef.cc #genere chainedef.o
CC -c chainedisp.cc #genere chainedisp.o
CC chainedef.o chanedisp.o -o prog
le
Cours de programmation
Laurent Henocque
Le langage C++
Le compilateur appelle automatiquement les constructeurs correspondant aux arguments fournis en mme temps que la
dclaration, et les destructeurs des variables locales
main(){
vector v(5); // appelle le constructeur un argument
vector w = 8; // appelle egalement ce constructeur
vector x;
...
} // appelle le destructeur de vector pour x, puis pour w puis pour v
//initialisation classique
vector v2 = v1;
v1 = v2;
Cours de programmation
Laurent Henocque
Le langage C++
// affectation
};
question : pourqoui la copie par dfaut des champs des objets n'est elle pas satisfaisante?
question : comment programmer ces deux fonctionsafin de remdier ce problme?
1.4.3. patrons
en C++, on peut galement dfinir des types gnriques, comme un "vecteur "de n'importe quoi". Dans l'exemple ci
dessous, le symbole T est un type paramtre pour le template VectorOf :
template<class T> class VectorOf {
T* v;
int sz;
public:
VectorOf (int s) { v = new T[sz = s]; }
};
void f() {
VectorOf<int> v1(100);
VectorOf<complex> v2(100);
}
on lance le contrle tout programme susceptible de traiterl' exception par l'intruction "throw"
Cours de programmation
Laurent Henocque
Le langage C++
int vector::operator[](int i) {
if (i<0 sz<=i) throw range();
return v[i];
}
on peut alors intercepter l'erreur dans un bloc spcialis de type "try {} catch{}"
void f(int i) {
try {
vector v[i];
v[i+1000] = 12; // exception assure
// programmes pouvant aussi provoquer une exception
} catch (vector::range){
error ("attention : bornes de tableau dpasses");
}
}
les convertisseurs permettent aussi de rduire la complexit des interfaces de programmation : une seule fonction
complex operator+ (complex,complex) traite trois situations ds lors qu'il existe une convertion de int vers
complex
10
Cours de programmation
Laurent Henocque
Le langage C++
public:
virtual void push(T) = 0; // pure virtuelle
virtual T pop(void)
= 0; // pure virtuelle
};
11
Cours de programmation
Laurent Henocque
Le langage C++
p->rotate();
}
Shape
center
color
vtbl
Circle
vtbl
&?::draw()
&?::rotate()
&Circle::draw()
&Circle::rotate()
12
Cours de programmation
Laurent Henocque
Le langage C++
ex smalltalk:
Stack s; // pile fourre tout
void main(){
s.push (new Peugeot(309));
s.push (new Boeing(727));
s.pop()->takeoff();
s.pop()->takeoff(); // erreur excution : une 309 ne vole pas
ex C++:
Stack s<plane>; // pile d'avions
void main(){
s.push (new Boeing(727)); // ok
s.push (new Peugeot(309)); // erreur compilation
s.pop()->takeoff();
Smalltalk permet de dfinir pour une classe un ensemble minimal d'oprations, l'utilisateur tant libre d'(essayer d')
appeler une fonction non dfinie la base
C++ permet de dfinir une interfaceexacte, toute erreur tant dtecte ds la compilation
sans l'hritage multiple, deux seulement des trois choixci dessus sont accessibles
C++ ne tient aucun compte de l'ordre de l'hritage pour rsoudre les ambiguts, et demande une dsambiguation
explicite
13
Cours de programmation
Laurent Henocque
Le langage C++
1.5.5. l'encapsulation
les fonctions oprant sur un objet sont encapsules dans la classe.
l'unit d'encapsulation est la classe, et non l'objet : un objet d'une classe possde tous les droits sur un autre objet de la
mme classe
en particulier, une classe C++ n'est pas un objet C++ : la classe n'est pas une entit palpable, mais une abstraction utile
seulement lors de la compilation
C++ permet de restreindre l'accs aux membres des classes, donnes ou fonctions, sans distinguer entre les
autorisations de lecture et d'criture pour les donnes membres
public donne l'accs tout programme
private interdit l'accs tout programme, y comprisun membre d'une classequi en hrite
protected donne l'accs aux seuls membres des (futures) sous classes
le mot clef friend permet de donner l'accs de faon explicite (toutes les fonctions d') une classe, o une fonction
dsigne explicitement
14
Cours de programmation
2.
Laurent Henocque
Le langage C++
Fonctions et fichiers
2.1. introduction
le fichier a un rle unique : dfinir la porte de fichier pour :
les fonctions static,
les fonctions inline,
les variables globalesstatic et
les variables globalesconst
cest aussi habituellement une unit de stockage et de compilation
// la variable a de fic1.cc
int f();
// la fonction f de fic1.cc
// dclaration ET dfinition
int b = 1;
// id
extern int c;
// dclaration seule
//fic2.cc
int a;
15
Cours de programmation
Laurent Henocque
Le langage C++
extern double b;
extern int c;
habituellement, les dfinitions de classes sont dcrites dans des fichiers d'en tte inclus par tous les fichiers qui les
utilisent
les fonctions inline ont une porte ddition interne
les constantes (const) aussi
les typedef sont locaux leur fichier galement. Attention, en C++ typedef ne sert pas dfinir un type mais dfinir
un nouveau nom pour un type, ou un nom de type composite.
on a la possibilit dedclarer des constantes externes explicites
extern const int a;
const int a = 1;
16
Cours de programmation
Laurent Henocque
Le langage C++
struct list{};
patrons
dclarations de fonctions
dclarations de variables
dclarations de constantes
dclarations d'numrations
dclarations de noms
struct list;
inclusions
#include
dfinitions de macros
commentaires
// et /* */
void g(){};
dfinition de donnes
17
Cours de programmation
Laurent Henocque
Le langage C++
ou encore
extern C {
char * strcpy(char *, const char *);
char * strcmp(const char *, const char *);
#ifdef __cplusplus
}
#endif
Note : la directive extern C spcifie la convention ddition de liens, mais le programme compil doit rester du C++,
qui est plus rigoureux que C, notamment sur lutilisation effective des arguments des fonctions
18
Cours de programmation
Laurent Henocque
Le langage C++
2.7.1. dclarations
une dclaration de fonction mentionne les types de la valeur de retour et des arguments et le nom de la fonction
une fonction est soit globale (comme une fonction C) soit membre d'une classe donne. On y accde alors avec les
oprateurs . et -> comme dans le cas des donnes membres.
class StackOfInt {
// ...
void push
(int data);
le passage d'argument est comparable linitialisation : les types sont vrifis et les conversions ncessaires qui sont
possibles sont ralises
les arguments peuvent tre nomms lors de la dclaration : cela rend les fichiers .h plus lisibles, car le nom d'un
argument claire souvent plus que son type sur son rle.
on peut fournir des valeurs par dfaut aux derniers arguments fournis dans la dclaration. Ces arguments sont alors
optionnels.
int fonction (int a, char* s = "", float f=2.0);
fonction(12); // ok : fonction(12,"",2.0);
fonction(12,"aze"); // ok : fonction(12,"aze",2.0);
19
Cours de programmation
Laurent Henocque
Le langage C++
on peut donner le type d'une fonction qui attend un nombre variable d'arguments.
int printf (char* format ...); // un char * puis autant d'arguments que voulu
des arguments peuvent rester inutiliss :il suffit de ne pas les nommer pour obtenir le calme du compilateur
une fonction peut tre dclare inline
inline int double (int a) {return 2*a;}
dans ce cas, le compilateur insre le code (assembleur si on veut) de la fonction chaque appel, et sait parfois mme
faire mieux :
inline int fact (int n) {return n<2 ? 1 : n*fact(n-1);}
int i=fact(5); // gnre i=120;
il faut utiliser const autant que possible, mme pour les passages d'arguments par pointeur, lorsque la fonction ne doit
pas modifier l'objet point
int strlen (const char *); // strlen ne modifie pas le contenu de la chane
un littral, une constante, ou un argument qui demande une conversion peuvent tre passs comme argument d'une
fonction qui attend const&(une rfrence un objet const), mais pas d'une fonction qui attend une rfrence non const
float fortran_sqrt(const float&);
void f(double d){
20
Cours de programmation
Laurent Henocque
Le langage C++
float r;
fortran_sqrt(2.0f);
fortran_sqrt(r);
fortran_sqrt(d);
c'est normal car l'original pass en argument rfrence non const est susceptible d'tre modifi par la fonction appele.
Ce n'est pas possible pour la constante 2.0f ci dessus, ni pour la temporaire de conversion de "d" en float : la conversion
inverse n'existe pas.
on ne peut retourner ni une rfrence, ni un pointeur vers une variable locale ou une constante locale :
int * f(){
int aux;
return &aux;//erreur
}
int & f(){
int aux;
return aux;//erreur
}
int & f() {return 1;} // erreur
21
Cours de programmation
Laurent Henocque
Le langage C++
print (1.0);
print (1);
//ok
print ("toto");
//ok
print (0);
22
Cours de programmation
Laurent Henocque
Le langage C++
dans ce dernier cas, noter que zro est un int : lambigut nat ici de ce qu'il existe deux conversions possibles
T&
T&
T[]
T*
T(args)
T(*)(args)
const T
volatile T
T*
const T*
T*
volatile T*
23
Cours de programmation
Laurent Henocque
Le langage C++
2.7.10.
1 : correspondance exacte
les squences de zro ou plus conversions triviales sont meilleures que toute autre squence.
celles qui ne convertissent pas vers const ou volatile sont meilleures que toutes les autres.
2 : correspondance avec les promotions
les squences qui ne contiennent que des promotions d'entiers, des conversions de float en double, et des triviales sont
meilleures que toutes les autres
3 : correspondance avec les conversions standard
les squences qui ne contiennent que des conversions standard et triviales sont meilleures que toutes les autres
4 : correspondance avec les conversions dfinies par l'utilisateur
5 : correspondance avec les points de suspension dans la dclaration
si deux correspondances existent au mme niveau de priorit, l'appel est ambigu et rejet
2.7.11.
on peut spcifier des valeurs par dfaut aux arguments d'une fonction. L'argument absent lors d'un appel effectif sera
remplac par cette valeur
ce n'est possible que pour les derniers arguments de la fonction
cela doit tre fait la dfinition de la fonction
void print (int d , int base=10);
f(){
print (3);// print(3,10);
print (4,16);
}
on peut simuler ce mcanisme par surcharge (et l'tendre aux autres arguments)
void error (char *text, int code);
inline void error (int code) { error ("no text here", code);}
2.7.12.
on utilise dans ce cas les points de suspension, qui permettent au compilateur d'accepter des arguments
supplmentaires, utiliss ou non par la fonction lors de l'appel
extern "C" int printf(const char * ...);
extern "C" int fprintf(FILE*, const char * ...);
24
Cours de programmation
Laurent Henocque
Le langage C++
va_start(ap,first);
//initialise
node *child;
//auxiliaire
//ncessaire
}
f(){
node *n=buildnode(new node(), new node(), (node*)0);
}
noter que 0 est un int, et que sizeof int est potentiellement diffrent de sizeof (node *), do le cast
2.7.13.
pointeur de fonction
lors d'une affectation un pointeur de fonction, le type de l'argument doit correspondre exactement, y compris pour sa
valeur de retour
les rgles de l'appel direct s'appliquent aux pointeursde fonction sans changement
on peut dfinir un type pointeur de fonction pour rendre plus aise la manipulation (cf. signal.h)
ces pointeurs sont utiles pour :
paramtrer la dynamique d'un systme (actions correspondant des menus par exemple)
25
Cours de programmation
Laurent Henocque
Le langage C++
raliser des procdures polymorphiques (comme la fonction "map" de lisp) : on passe l'adresse d'une fonction en
paramtre une autre pour effectuer un traitement global (tri d'un tableau d'objets inconnus pour lequel on mentionne un
fonction de comparaison exemple de qsort dans libC)
on peut prendre l'adresse d'une fonction inline, ou d'une fonction surcharge
2.8. macros
elles sont d'un usage plus limit en C++ qu'en C, cause de "template", "inline", et "const"
elles sont parfois utiles
les compilateurs et dbuggers sont largus, parce que les macros gnrent du code sur une seule ligne, et le
prprocesseur est invoqu avant la compilation proprement dite
#define ma_macro du texte a qui mieux mieux
#define
le texte p enrob
donnent l'utilisation :
ma_macro fada
-> du texte a qui mieux mieux fada
avec_param(qui suit est)
-> le texte qui suit est enrob
2.9. macros
lorsqu'un argument d'une macro intervient dans une expression, la macro doit le parenthser
lorsqu'un argument d'une macro est une squence d'instructions, la macro doit le mettre entre accolades
dans une macro, utiliser les commentaires /* */ la C
les mentions de noms globaux dans une macro doivent tre prfixes de "::", afin de ne pas subir de masquage local
intempestif
lorsque le rsultat de la substitution est une squence d'instructions, la macro doit la mettre entre accolades.
Par exemple :
#define carre(a) a*a
#define fonc(prog) if () prog else exit(); validate();
26
Cours de programmation
Laurent Henocque
Le langage C++
2.9.1. tapes
le pr processeur ralise les oprations suivantes :
des caractres de passage la ligne sont introduits pour remplacer les indicateurs de fin de ligne dpendant du systme
(ainsi que toute autre traduction dpendant du systme). les squences trigraphes sont remplaces
(voir ci dessous)
la paire du caractre \ suivi d'un passage la ligne est efface
le source est dcompos en symboles de pr traitement et squences d'espaces. Chaque commentaire est remplac par un
unique espace
les directives sont excutes et les macros sont gnres
les squences d'chappement dans les chanes sont remplaces par leur quivalent
les littraux chaine adjacents sont concatns
la compilation peut enfin avoir lieu
??/
??'
??(
??)
??!
??<
??>
??-
2.9.3. oprateur #
suivi d'un paramtre de macro, les deux sont remplacs par la chaine de caractres fournie en argument rel de la
macro
2.9.4. oprateur ##
il permet de concatner un symbole et un paramtre de macro, en supprimant les espaces
cela permet de crer de nouveaux symboles
27
Cours de programmation
Laurent Henocque
Le langage C++
#else
#elsif
2.9.10.
directive d'erreur
#error chaine-symbole
2.9.11.
pragmas
#pragma chaine-symbole
2.9.12.
directive nulle
#
n'a aucun effet
28
Cours de programmation
2.9.13.
Laurent Henocque
Le langage C++
noms pr dfinis
__LINE__
__FILE__
__DATE__
__TIME__
__cplusplus
__STDC__ est dfini par certains compilateurs
les compilateurs dfinissent normalement de nombreux symboles qui permettent de rendre du code dpendant du
systme, de la machine, du niveau de respect du standard C++
2.10. exercices
2.10.1.
exercice
crire des dclarations de fonctions prenant des pointeurs de fonctions en arguments et retournant de tels pointeurs
2.10.2.
exercice
2.10.3.
exercice
crire un programme qui affiche Hello suivi de tous les arguments de la ligne de commande
2.10.4.
exercice
crire le programme cat, qui lit les fichiers nomms sur la ligne de commande et les crit sur sa sortie standard
2.10.5.
exercice
programmer une fonction de tri "sort" prenant une fonction de comparaison en argument
2.10.6.
exercice
2.10.7.
exercice
programmer itoa
29
Cours de programmation
2.10.8.
Laurent Henocque
Le langage C++
exercice
2.10.9.
exercice
2.10.10.
exercice
crire un programme de cryptage qui utilise une clef passe en paramtre dont les caractres sont combins de faon
itrative aux caractres du fichier traduit
2.10.11.
exercice
2.10.12.
exercice
dfinir des rgles typographiques pour marquer la diffrence entre les diffrentes entits nommes par vos programmes
(fonctions, pointeurs vers, variables locales, globales, etc)
2.10.13.
exercice
2.10.14.
exercice
crire un programme qui appelle une fonction (sqrt par exemple) de la bibliothque C standard (sans include <math.h>)
30
Cours de programmation
3.
Laurent Henocque
Le langage C++
Classes
3.1. classes et membres
les classes sont des types dfinis par l'utilisateur
aucun type de base de C++ n'est une classe
3.1.2. classes
le type "class" permet la restriction des appels : seules des fonctions "autorises" pourront invoquer une fonction
membre, ou bien agir sur un membre (lire o modifier)
cela permet une localisation plus facile des erreurs : tout tat erron est le fait des seules fonctions membres
class individu {
char *nom;
int age;
public:
void set (char *nom,int age);
void print();
};
31
Cours de programmation
Laurent Henocque
Le langage C++
on ne peut pas assigner this, mais on peut modifier l'objet point. Pour une classe X, le type de this dans les fonctions
membres est :
X *const this;
utiliser this pour dsigner l'objet n'est pas ncessaire : les membres d'une classe sont accessibles directement par les
fonctions membres d'un objet
class X {
int _a;
void f(int a) {_a = a;} // signifie this->_a = a;
};
un membre const peut tre invoqu sur un objet const, une fonction ordinaire ne peut pas
noter que le compilateur ne dtecte pas seul les tentatives de modification d'un objet const : il est essentiel de faire
figurer ce type dans la dclaration des fonctions
le type de this dansun membre const de la classe X est
const X *const
C'est utile pour modifier physiquement un objet dont l'tat logique n'est cependant pas affect par l'opration : par
exemple pour implanter un compteur d'accs l'objet (cas ci dessus). On distingue la constance logique de la constance
physique.
3.1.5. initialisation
dans une classe X, on peut dfinir des fonctions membres d'initialisation qui portent le nom X
class individu {
char *
int
_nom;
_age;
32
Cours de programmation
Laurent Henocque
Le langage C++
lors de la cration d'objets d'une classe donne, on doit fournir les argument attendus par le constructeur utilis :
main(){
individu bob("bob",34);
individu *paulptr = new individu("paul",23);
}
3.1.6. initialisation
on dfinit en gnral de multiples constructeurs, avec des arguments par dfaut
individu::individu(char *nom="", int age=0):_nom(nom),_age(age){}
la copie par dfaut est une copie champ champ (chaque champ est copi avec son propre constructeur de copie s'il
existe
si aucun constructeur de copie n'existe, pour la classe comme pour les donnes membres, la copie par dfaut est celle
de la structure : recopie bit bit
on peut crer un tableau d'instances d'un classe condition que cette classe dfinisse un constructeur sans paramtre.
On ne peut pas passer de paramtre au constructeur pour initialiser tous les objets d'un tableau
Attention : un constructeur un seul argument peut tre appel automatiquement par le compilateur pour convertir un
argument lors d'un appel de fonction. Pour l'empcher, on utilise le mot clef
explicit dans la dclaration du constructeur.
3.1.7. destruction
en gnral, les objets qui ont t crs doivent faire un peu de mnage quand on les jette
cela se produit automatiquement la sortie du bloc de porte pour les variables automatiques, et explicitement par
appel de delete pour les objet allous
C++ garantit l'appel automatique des destructeurs des objets crs dans ces deux situations, dans l'ordre inverse des
appels de constructeurs correspondants
le destructeur pour une classe X porte le nom ~X
33
Cours de programmation
Laurent Henocque
Le langage C++
individu::individu(char *nom):_age(0){
_nom = new char [1+strlen(nom)];//acquisition de mmoire
strcpy(_nom,nom);
}
individu::~individu(){
delete[] _nom;//libration dans le destructeur
}
int getage();
};
inline int individu::getage(){return _age;}
cela sert un objectif de performance : pas de surcot la dfinition d'une classe "propre"
les fonctions membres dfinies au sein de la dfinition de la classe sont automatiquement inline
elles peuvent tre dclares hors de la classe
34
Cours de programmation
Laurent Henocque
Le langage C++
35
Cours de programmation
Laurent Henocque
Le langage C++
36
Cours de programmation
Laurent Henocque
Le langage C++
};
on peut aussi accder des symboles globaux masqus par un symbole local
class MyFile {
void open(){
}
};
cela sert en cas de besoin reconnu, pour des classes embotes simples. Le mcanisme utile (accs par la seule classe
englobante) peut tre obtenu parl'utilisation de classes amies :
class Y{ friend class X;
int i;
Y():_i(0){}
37
Cours de programmation
Laurent Henocque
Le langage C++
};
class X{
Y* head;
public:
X():head(new Y()){}
};
Un type embot peut tre atteint directement par qualification de porte : X::Y. Une classe imbrique possde le mme
statut que tout autre classe. Un membre qui retourne une valeur d'un type embot se dclare ainsi :
T1::T2 T1::f();
un membre statique est une donne globale, dont la visibilit et restreinte la classe, sauf s'il est public
une fonction membre statique n'est visible que dans le fichier qui la dfinit
Attention : il y a ncessit de dfinir et initialiser les membres statiques dans le fichier .cc, car leur dclaration "static"
dans la classe n'est qu'une dclaration
38
Cours de programmation
Laurent Henocque
Le langage C++
cl * p = &z2;
PMFI pf = &cl::print;
z1.print(1)
(z1.*pf)(2);//parenthses obligatoires
z2->print (3);
(z2->*pf)(4);//parenthses obligatoires
}
une union nomme est une struct dont chaque membre possde la mme adresse, utile dans le cas rarissime o l'on sait
qu'un seul membre d'une structure est utis un moment donn. Une programme C++ avec des unions est en gnral un
mauvais programme C++
union token {
char *p;
char v[8];
long i;
double d;
token(const char*);//pb : p ou v ? : dcid par programme par ex
token (long _i):i(_i){}
token (double _d):d(_d){}
};
le compilateur ne sait pas quelle est la donne valide un moment donn : pas de vrification
on peut utiliser des constructeurs surchargs pour initialiser une union
on a un problme de vrification de conformit au type : on encapsule souvent l'union dans une classe qui mmorise le
type, ne serait-ce que pendant les phases de dveloppement et de tests, afin d'viter de douloureuses msaventures.
struct Token {
enum Type {Double, Long, StringPtr, StringArray};
private:
Type type;
union token {
char *p;
char v[8];
long i;
double d;
};
39
Cours de programmation
Laurent Henocque
Le langage C++
public:
Token(char *pp);
Token(long ii):i(ii),type(Long){}
Token(double dd):d(dd),type(Double){}
long& ival(){assert(type==Long);return i;}
long& dval(){assert(type==Double);return d;}
long& sval(){assert(type==StringPtr);return s;}
long& aval(){assert(type==StringArray);return v;}
};
de tel classes unions type maintenu fournissent une solution lgante pour dcrire des fonctions arguments
variables scurises
extern Token NOTHING;
void message(const char * pattern, Token a1=NOTHING, Token a2=NOTHING, Token
a3=NOTHING);
les constructeurs permettent alors la conversion lors de l'appel en passant des arguments normaux, qui sont
rceptionns en toute scurit aprs l'appel
table t3(200);
t3 = t2;
//oprateur d'affectation
le destructeur est appel pour t2, mais pas le constructeur, et le t3 original pas dsallou
pour viter ces problmes il faut dfinir le constructeur par copie et l'affectation
40
Cours de programmation
Laurent Henocque
Le langage C++
delete ptr;
// ok
delete tab;
// erreur
delete[] tab;
// ok
on ne peut allouer un tableau d'instances d'une classe que si elle possde un constructeur sans argument
oublier d' appeler delete perd dfinitivement de la mmoire
appeler delete deux fois sur un mme pointeur est probablement fatal
41
Cours de programmation
Laurent Henocque
Le langage C++
l'oprateur new global reste accessible si besoin est par ::new, sauf s'il a t lui mme masqu, ce qui est trs
dsagrable
si l'on implante un allocateur pour un besoin spcifique, il est bon de pas masquer pour la classe l'oprateur new
habituel : on surcharge donc new en mentionnant un argument supplmentaire
typedef HEAP ;
class X{
void *operator new (size_t,HEAP);//spcifique
void *operator new (size_t){return ::new char[size_t];};//standard
void operator delete(void*, size_t);
};
noter que si l'on a plusieurs "new" on a un seul delete, ce qui peut poser quelques problmes
enfin, si l'on alloue des blocs de taille constante, on peut ignorer l'argument taille de new, et utiliser une version de
delete sans argument taille
on peut jusqu' doubler la vitesse d'un programme en allouant bien les petit blocs beaucoup utiliss (maillons de liste
chaine par exemple)
3.5. exercices
3.5.1. exercice
concevoir une structure Noeud d'arbre binaire avec des constructeurs et destructeurs
42
Cours de programmation
Laurent Henocque
Le langage C++
3.5.2. exercice
modifier la classe intset pour en faire un ensemble de Noeuds, un ensemble de chanes
3.5.3. exercice
dfinir une classe pour l'analyse, la mmorisation et l'valuation d'expressions arithmtiques entires simples (le
constructeur reoit la chaine de caractres qui reprsente l'expression)
3.5.4. exercice
concevoir une classe table des symboles, et une classe "entre de table des symboles"
3.5.5. exercice
utiliser la construction d'un objet global pour afficher du texte avant le main et aprs
3.6.
43
Cours de programmation
4.
Laurent Henocque
Le langage C++
Hritage
4.1. introduction et tour d'horizon
l'hritage permet de dcrire une hirarchie entre les diffrents types de donnes manipuls par un programme. La
relation fondatrice de cette hirarchie est la relation "est une sorte de". Cette relation logique est celle qui doit guider la
dcision d'untiliser l'hritage autant que possible.
les classes hrites permettent de dcrire despoints communs entrediffrentes classes
l'hritage multiple permet de combiner des caractristiques issues de plusieurs super classes soit par ajout simple (on
parle alors de mixin - pour mixing in -) soit pour hriter d'une part d'une implmentation, d'autre part d'une interface de
programmation. Cess notions sont dtailles dans le cours de programmation objet.
44
Cours de programmation
Laurent Henocque
Le langage C++
45
Cours de programmation
Laurent Henocque
Le langage C++
quand une classe hrite virtuellement, une fonction virtuelle de la classe de base peut tre effectivement implante par
une classe soeur.
l'hritage virtuel est implant au travers de pointeurs internes l'objet et prsente un cout non nul (compens par la
non rptition)
46
Cours de programmation
Laurent Henocque
Le langage C++
tant que le type rel est le type de l'objet spcifi, le compilateur connat la taille de l'objet dtruire.
dans le cas contraire, on doit utiliser un destructeur virtuel. Attention, il est toujours prfrable d'utiliser des
destructeurs virtuels !!!
On peut vouloir placer dans un espace de stockage particulier, ce qui est utile pour faire du backtracking, ou stocker
des donnes en diffrents espaces (rmanents, partags, etc.) :
class storage {
virtual void * alloc(size_t);
virtual void
free(void *, size_t);
};
void *operator new(size_t s, storage & loc) {
return loc.alloc ( s );
}
47
Cours de programmation
Laurent Henocque
Le langage C++
Lors de la destruction, il faut appeler explicitement le destructeur (qui doit donc tre virtuel si l'opration est faite par
free soi mme), et ensuite prvenir le systme de stockage:
p->~X(); maPileDobjets.free(p);
48
Cours de programmation
5.
Laurent Henocque
Le langage C++
Dclarations et constantes
5.1. dclarations
en C++ un nom doit tre dclar
la dclaration stipule le type de l'objet
syntaxe : nom de type + nom de variable [ + "=" + valeur];
quand il y a valeur, c'est une dclarationet une dfinition.
Exemples : dterminer les dfinitions :
char ch;
int count =1;
char * name;
struct complex {float re, im};
complex cvar;
extern complex sqrt(complex);
extern int error_number;
typedef complex point;
float real(complex *p) { return p->re;};
const double pi = 3.1415926...;
struct user;
template<class T> abs(T a) {return a<0 ? -a : a; }
enum car {peugeot, citroen, volvo};
{ }
classe
class { } ;
fonction
T f() { }
fichier
static
49
Cours de programmation
programme
Laurent Henocque
Le langage C++
extern
::
int x;
main(){
int x= 1;
x = x + ::x;
}
50
Cours de programmation
Laurent Henocque
Le langage C++
un nom de type peut aussi tre utilis pour spcifier une conversion explicite d'un type vers un autre
char *p;
long l = long(p); // convertit de pointeur vers long
51
Cours de programmation
Laurent Henocque
Le langage C++
on est garanti qu'un char contiendra les entiers de 0 127 ; supposer plus est non portable
donner le type unsigned n'empche pas de copier une valeur ngative : cela n'agit que sur les rgles de l'arithmtique
unsigned int bitmask = -1;
// meilleur
256+255;
pointeur,
&
rfrence,
52
Cours de programmation
Laurent Henocque
[]
tableau,
()
fonction,
struct
structure
Le langage C++
exemples :
int* a;
float v[10];
chat-r *p[20];
void f(int);
struct str{int a; char *s;};
les parenthses peuvent tre utilises dans les cas o la prcdence des oprateurs n'est pas celle souhaite
int *v[10];
int (*p) [10];
on peut dclarer plusieurs noms ensemble spars par une virgule (mais il faut viter de le faire)
int *p, q; // q n'est pas un pointeur
free (s);
}
5.3.6. pointeurs
pour la plupart des types T, ladclaration d'un pointeur sur T est noteT*
int * pi;
char **ps;
int (*vp)[10];
53
Cours de programmation
Laurent Henocque
Le langage C++
*V
ou encore
5.3.7. tableaux
dclaration
T[taille];
les lments sont indexs de 0 taille - 1;
pas de virgule pour les dimensions suprieures a un
int tab[2][5]; //un tableau de deux tableaux de cinq entiers
initialisation statique
char t[]="abcdefghijkl";
char v[2][5] = {{1,2,3,4,5},{'a','b','c','d','e'}};
utilisation
main (){
for (int i=0; i<2 ; i++)
for (int j = 0; j<5 ; j++)
cout << v[i][j] << endl;
}
l'affectation un tableau est impossible, il faut faire une copie lment par lment
54
Cours de programmation
Laurent Henocque
Le langage C++
5.3.9. structures
on appelle structure un agrgat arbitraire d'objets de types quelconques
struct adresse {
char * nom;
int numro;
char * rue;
int code;
char * pays;
}; // noter le point virgule final
l'accs aux membres des structures se fait par les oprateurs "" et->"
"
adresse add;
add.nom = "James Bond";
add.number = 007;
adresse *padd = &add;
cout << padd->nom << " " << padd->number << endl;
5.3.10.
structures
le nom d'un type est utilisable ds qu'il a t vu, pourvu que son emploi ne ncessite pas de connatre la taille de la
structure
55
Cours de programmation
Laurent Henocque
Le langage C++
struct maillon {
maillon *suivant;
};
et encore :
class S;
extern S a;
S f();
void g(S);
par contre :
void h(){
S a; //erreur S inconnu
f(); //id
g(a);//id
}
on ne peut dclarer une instance d'un type structure avant que la dfinition du type n'ait t vue entirement
struct mauvaise {
mauvaise elem;
// refus
};
5.3.11.
structures
la gestion des rfrences croises (list de links qui pointent sur la liste) se fait par des dclarations pralables :
struct link;
//dclaration pralable
struct list {
link *l;
};
struct link {
link *next;
list *pere
};
5.3.12.
quivalences de types
deux types sont diffrents mmes s'ils ont les mmes membres et ne sont pas interchangeables
56
Cours de programmation
Laurent Henocque
Le langage C++
//impossible
int i =x;
//impossible
on utilise typedef pour dfinir de nouveaux (noms de) types partir d'existants
typedef char * String;
String p1, p2;
char * q1,q2; //attention ici q2 est char !
5.3.13.
rfrences
une rfrence est un nom alternatif un objet : les oprateurs agissent sur l'objet rfrenc
au travers de la rfrence
int i = 0;
int& j = i;
j++;
l'initialiseur d'une rfrence doit donc tre une l_value (sauf cas particulier ci aprs)
les rfrences servent essentiellement pour
le passage d'arguments par adresse
les valeurs de retour de fonction
les dfinitions d'oprateurs
une rfrence est un alias : on ne peut prendre une double rfrence
int i = 0;
int& j = i;
int&& k = j; // impossible
5.3.14.
rfrences
//impossible
//ok
les rfrences permettent l'utilisation d'un appel de fonction en l_value ( gauche du signe =)
57
Cours de programmation
Laurent Henocque
Le langage C++
struct assoc {
char *nom;
int value;
};
int&value(char*nom){
assoc *courant;
//recherche de nom
return courant->value;
}
main(){
char buf[80];
while (cin>>buf) {
value(buf)++;
}
}
5.3.15.
rfrences
les rfrences permettent de faire voluer une interface fonctionnelle qui copie des structures (petites) vers une
interface qui copie des pointeurs sans modifier les programmes qui utilisent cette interface
struct data {};
//version 1
data f(){}
main(){
data res=f();
}
//version 2
const data& f(){}
main(){
data res=f(); // cet appel ne change pas
}
58
Cours de programmation
Laurent Henocque
Le langage C++
passage la ligne
tabulation horizontale
NL(LF)
HT
tabulation verticale
effacement
\n
\t
VT
BS
\v
\b
retour chariot
CR
\r
saut de page
FF
\f
alerte
BEL
\a
anti slash
\\
caractre
\?
caractre
'
\'
caractre
"
\"
caractre valant 0
NUL
\0
caractre en octal
ooo
caractre en hexa
hhh
utiliser des constantes explicites (octales ou hexa) rend les programmes non portables entre machines ayant des jeux de
caractres diffrents
une constante octale ou hexa se termine au premier caractre non octal ou non hexa
char *s="voici un caractre idiot \x8E345AB insr dans une chane";
59
Cours de programmation
Laurent Henocque
Le langage C++
char s[]=
char s[]=
char s[]=
char s[]=
char s[]=
5.4.5. zro
c'est un int utilisable comme constante de tout type entier, pointeur, ou flottant.
void f(int);
void f(char *);
main(){
f(0); // le compilateur refuse cet appel : ambigu
f(int(0)); //ok
f((int)0); //ok, coercition a la C
f((char *)0);//ok
}
gnralement, quand c'est possible, il correspond un mot dont les bits sont tous a zro
unsigned bitmask = ~0; // bits tous a un
C++ recommande d'utiliser 0 pour dsigner le pointeur nul plutt que la macro NULL habituellement dfinie dans des
fichiers include de l'utilisateur ou des bibliothques
60
Cours de programmation
Laurent Henocque
Le langage C++
const est un modifieur de type : il dcrit comment une donne doit tre utilise
const char * peek(int i) {
return tab[i]; //l'appelant ne peut pas changer tab[i]
}
void f(const char *);
void f(char *);
//ok
s1[3]='e';
//interdit
//interdit
s2[3]='e';
//ok
//interdit
s3[3]='e';
//interdit
5.5.3. numrations
pour dclarer des constantes, on peut galement utiliserenum
enum {ASM, AUTO, BREAK}; // dclare trois valeurs
forme quivalente :
const int ASM =0;
const int AUTO =1;
const int BREAK =2;
une numration peut tre nomme. Attention, il ne faut pas utiliser la syntaxe "typedef enum" comme en C.
enum motclef {ASM, AUTO, BREAK}; // motclef devient un type
61
Cours de programmation
Laurent Henocque
Le langage C++
la conversion d'enum vers int est automatique mais la conversion inverse doit tre rendue explicite, ce qui rend souvent
les numrs assez dsagrables utiliser
int i = ASM; // ok
motclef var1 = 2; // rejet
int j = 1;
motclef var = motclef(i); ok
les enumrations sont parfois meilleures que les int correspondants : elles permettent au compilateur de gnrer des
messages si l'un des cas est oubli dans un switch.
};
5.6.2. unions
on veut utiliser la mme structure pour stocker des donnes diffrentes suivant les moments
exemple : table des symboles,dont une entre contient nom et valeur, de type entier ou chane.
struct entre {
char type;
char *nom;
62
Cours de programmation
Laurent Henocque
Le langage C++
sur certaines machines, int et pointeur n'auront pas la mme taille : ce n'est pas une simple conversion
certains programmeurs les utilisent pour convertir sans que le compilateur ne rechigne (c'est vilain : mauvaise
utilisation du concept)
struct cast {
union baduse{ //on peut la nommer
int i;
int *p;
};
};
main(){
cast c;
c.i = 12;
int *p=c.p; //a vomir
}
5.7. exercices
5.7.1. exercice
crire un programme qui affiche les tailles de tous les types fondamentaux, et de types pointeurs vers, tableaux et
structures qui en drivent.
5.7.2. exercice
crire un programme qui affiche sous forme d'entiers les adresses relatives de champs de structures
5.7.3. exercice
crire une fonction qui permute deux entiers
5.7.4. exercice
afficher la configuration de bits du pointeur 0 sur votre machine
5.7.5. exercice
afficher tous les caractres utiles et leurs valeurs comme entiers
63
Cours de programmation
Laurent Henocque
Le langage C++
5.7.6. exercice
dfinir un fichier de dfinitions pour des types de base de taille connue avec exactitude. (pour la portabilit).
5.7.7. exercice
crire des dclarations pour
un pointeur sur un caractre
un tableau de 10 entiers
un pointeur sur un tableau de chanes de caractres
un pointeur sur un pointeur de caractre
une constante entire
un pointeur sur une constante entire
un pointeur constant sur une constante de type entier
crire les initialisations et compiler
64
Cours de programmation
6.
Laurent Henocque
Le langage C++
Expressions et instructions
6.1. sommaire des oprateurs
6.1.1. oprateurs
voici un tableau synoptique des oprateurs du langage C++, avec les conventions suivantes :
les oprateurs sont prsents par ordre de prcdence dcroissant
dans la mme boite, la prcdence est la mme
objet est une expression donnant une instance d'une classe et l_value est une expression reprsentant un objet non
constant
::
rsolution de porte
classe::membre
::
global
::nom
slection de membre
objet.membre
->
slection de membre
objet->membre
[]
indexation
pointeur[expression]
()
appel de fonction
expression(liste
()
construction de valeur
type(liste dexpression)
sizeof
sizeof expression
sizeof
sizeof (type)
dexpression)
6.1.2. oprateurs
++
pr et post incrmentation
++lvalue et lvalue++
--
pr et post dcrmentation
--l_value et l_value--
complment 2
~expr
non
!expression
-,+
-expression, +expr
&
adresse de
&lvalue
drfrence
*pointeur
new
crer
new type
delete
dtruire
delete pointeur
65
Cours de programmation
Laurent Henocque
Le langage C++
delete[]
dtruire tableau
delete[] pointeur
()
coercition (conversion)
(type) expression
.*
section de membre
objet.ptr_de_membre
->*
section de membre
ptr->ptr_de_membre
*, /, %
expression op expression
+, -
plus, moins
expression op expression
<<, >>
dcalage
expression op expression
comparaisons
expression op expression
==, !=
gal diffrent
expression op expression
&
et bit bit
expression op expression
6.1.3. oprateurs
^
expression op expression
ou bit bit
expression op expression
&&
et logique
expression op expression
||
ou logique
expression op expression
? :
expression conditionnelle
expression ? expression :
affectation simple
l_value = expression
op=
op et affectation
expression
66
Cours de programmation
Laurent Henocque
Le langage C++
virgule (squence)
expr,expr
6.1.4. associativit
les oprateurs unaires et d'affectation sont associatifs droite
tous les autres associent gauche, y compris les oprateurs postfixs
a=b=c
*p++
signifie (a=(b=c))
signifie (*(p++))
a<b<c
6.1.5. parenthses
les parenthses permettent de contrler l'associativit, et l'ordre d'valuation en partie du fait de la prcdence des
oprateurs
//v[1]=1 ou v[2]=1;
i=v[i++];
//valeur de i indfinie
value en (x*y)/z
(x*y)/z
67
Cours de programmation
Laurent Henocque
Le langage C++
nom:
identificateur
operator operateur
nom_fonction_conversion
~nom_classe
nom_classe_qualifi::nom
6.1.8. indexation
a[b] est identique par dfinition *((a)+(b))
ce n'est plus vrai pour l'oprateur [] quand il est dfini pour un type utilisateur videment
6.1.10.
68
Cours de programmation
6.1.11.
Laurent Henocque
Le langage C++
6.1.12.
leur effet sur les pointeurs est celui de l'arithmtique des pointeurs (qu'ils soient prfixes ou postfixes)
char * strcpy (char *p, const char *q) {
while(*p++ = *q++);
return p;
}
6.1.13.
sizeof
sizeof(char) == 1
6.1.14.
l'oprateur new
new essaye de crer un objet du type demand, et retourne un pointeur sur cet objet
si l'objet est un tableau, un pointeur sur le premier lment est retourn
new int;
//type int *
new int[20];
//type int *
new int[i][50];
//type int(*)[10]
dans ce cas la premire dimension peut tre variable, les autres constantes
on peut dfinir des allocateurs supplmentaires, ou surcharger l'oprateur new par dfaut
new (a,b,c) T;
void *operator new(size_t) peut tre appel avec l'argument 0 : un pointeur vers un objet toujours diffrent est retourn
chaque classe peut dfinir un oprateur new pour ses instances
69
Cours de programmation
Laurent Henocque
Le langage C++
class T;
new T; //appel de void *T::operator new(size_t) s'il existe
new U;
6.1.15.
l'oprateur new
on peut utiliser explicitement la version parenthse de new si on a un problme cause de parenthses dans le type :
new(int (*[15])(char)); //tableau de 15 pointeurs vers fonctions
6.1.16.
l'oprateur delete
6.1.17.
70
Cours de programmation
Laurent Henocque
Le langage C++
un pointeur vers B peut tre converti en pointeur vers D qui hrite de B si B n'est pas classe de base virtuelle (suppose
que B apparat comme sous objet dans D : les valeurs de ces deux pointeurs sont normalement diffrentes)
le pointeur nul est toujours converti en lui mme
un objet peut tre converti en rfrence X& si un pointeur sur cet objet peut tre converti en X*
la conversion vers une rfrence ne provoque pas d'appel de fonction de coercition, ni de constructeur
le rsultat d'une coercition vers une rfrence est une l_value (le seul cas)
6.1.18.
on peut convertir des pointeurs vers fonctions en pointeurs vers objets et rciproquement condition que les tailles
soient compatibles (danger l'utilisation)
un pointeur vers fonction peut tre converti en pointeur vers une autre fonction : l'appel travers ce nouveau pointeur a
des effets imprvisibles
un objet ou une valeur peut tre converti en objet d'une classe seulement si un constructeur ou un oprateur a t
dclar
un pointeur sur membre peut tre converti en un pointeur sur membre diffrent quand :
les deux pointent sur des membres de la mme classe ou
les deux pointent sur des membres de classes dont l'une drive de l'autre sans ambigut
on peut convertir un type constant (objet, rfrence d'une part ou pointeur) vers un type non constant (rfrence ou
pointeur seulement) : on obtient le mme pointeur ou objet. Toutefois son utilisation pour modifier l'objet peut provoquer une
exception d'adressage (dpend de la mise en oeuvre)
on peut convertir de volatile vers non volatile
6.1.19.
* lie son second argument, de type pointeur sur un membre de T, son premier argument, de type T ou d'une classe
dont T est classe de base accessible
id pour ->* avec un pointeur
le rsultat est un objet ou une fonction
si c'est une fonction, il peut tre utilis pour un appel
class A{
int f1(void *);
int f2(void *);
};
typedef int (A::*Afptr)(void *);
main(){
Afptr pt = A::f1;
A a;
(a.*pt)(0);
}
71
Cours de programmation
6.1.20.
Laurent Henocque
Le langage C++
oprateurs de multiplication
6.1.21.
oprateurs d'addition
6.1.22.
oprateurs de dcalage
6.1.23.
6.1.24.
72
Cours de programmation
Laurent Henocque
6.1.25.
Le langage C++
2 4, 3 & 2
6.1.26.
oprateur conditionnel a ? b : c
6.1.27.
affectation =, += etc
l'oprande gauche doit tre une l_value modifiable, qui donne son type au rsultat et l'expression
l'oprande droit doit pouvoir tre converti dans le type attendu gauche avant affectation (pas les numrations)
T* = T*const //OK
T*const = T* // impossible
ptr [sur membre] = ptr [sur membre] //OK
ptr [sur membre] = 0; //OK
T, volatile T = const T, volatile T; //OK
class X = ; // dfini par X& X::operator=(const X&);
class X = ; // sinon affectation membre membre
class X = class Y; // OK ssi Y hrite de X de faon non ambigu
T& = ; // affecte l'objet rfr
X op= Y est identique X = X op (Y), sauf que X n'est valu qu'une seule fois
6.1.28.
virgule associe et value de gauche droite, et la valeur de l'expression gauche est abandonne
le type est celui de l'expression de droite
6.1.29.
expressions constantes
elles sont ncessaires dans certaines situations : case, bornes de tableaux, longueurs de champs de bits, initialiseurs de
types numrs
elles sont connues et values la compilation, remplaces par leur valeur
elles consistent en :
des littraux
des expressions sizeof
des numrs
73
Cours de programmation
Laurent Henocque
Le langage C++
des valeurs const de types entiers initialises par des expressions constantes
6.1.30.
//cast
complex(n).re;
//fonction
6.1.31.
74
Cours de programmation
Laurent Henocque
Le langage C++
expression ;
if ( expression ) instruction
if ( expression ) instruction else instruction
switch (expression) instruction
while (expression) instruction
do instruction while (expression)
for (instruction_for expression ; expression ) instruction
case expression-constante : instruction
default : instruction
break;
continue;
return expression ;
goto identificateur ;
indentificateur : instruction
instruction for :
dclaration
expression
6.2.2. if
l'utilisation de if se fait comme en C. Certains tests peuvent tre supprims en utilisant l'oprateur de slection
conditionnelle (?:), mme en l_value, ce qu'ignorent beaucoup de programmeurs :
if (a<b) {
max = b ;
b_used = 1;
} else {
max = a;
a_used = 1;
}
devient :
max = (a<b) ? b : a;
75
Cours de programmation
Laurent Henocque
Le langage C++
6.2.3. switch
switch est plus performant que if lorsqu'une expression est compare des constantes
le compilateur peut informer sur des oublis lorsque lon utilise des types numrs
6.2.4. goto
goto est utile dans des programmes gnrsautomatiquement (analyseurs syntaxiques)
utile dans des cas particuliers de besoin en performance dans une boucle temps rel par exemple
galement et surtout pour sortir dune boucle de faon brutalelors en conomisant des tests
void f(int a){
int i, j;
for (i=0 ; i<n ; i++)
for (j=0 ; j<n ; j++)
if (nm[i][j] == a) goto found;
// not found
// ... return
found:
// found
}
6.4. exercices
6.4.1. exercice
crire linstruction while quivalente linstruction for suivante :
for (i=0
; i<maxlen ; i++)
if (input[i] == ?) quest++;
76
Cours de programmation
Laurent Henocque
Le langage C++
6.4.2. exercice
parenthser les expressions suivantes :
a = b + c * d << 2 & 8
a & 077 != 3
a == b || a == c && c < 5
c = x != 0
0 <= i < 7
f(1,2) + 3
a = -1 + + b -- - 5
a = b == c++
a =
b= c =0
a[4][2] *= * b ? c : * d * 2
a-b,c=d
6.4.3. exercice
trouvez 5 constructions C++ diffrentes dont la signification est indfinie
trouvez dix exemples de code C++ non portable
que se passe til lors dune division par zro sur votre systme
que se passe til lors de dpassement de capacit par ajout excessif, retrait excessif
6.4.4. exercice
parenthser correctement les expressions suivantes :
*p++
*--p
++a-(int*)p->m
*p.m
*a[i]
6.4.5. exercice
crire strlen, strcpy, strcmp
6.4.6. exercice
observer les ractions du compilateur aux erreurs suivantes
void f(int a, int b) {
77
Cours de programmation
Laurent Henocque
Le langage C++
if (a = 3) // ...
if (a&077 == 0) //...
a := b+1;
6.4.7. exercice
crire la fonction cat qui concatne deux chanes
crire reverse, une fonction qui renverse une chaine
6.4.8. exercice
crire un programme qui limine les commentaires C++ dans un programme
attention aux chanes de caractres
6.4.9. exercice
que fait le programme suivant , et pourquoi lcrire :
void send (register*to, register *from, register count){
register n=(count+7)/8;
switch (count%8){
case 0 : do {
*to++ = *from++;
case 7:
*to++ = *from++;
case 6:
*to++ = *from++;
case 5:
*to++ = *from++;
case 4:
*to++ = *from++;
case 3:
*to++ = *from++;
case 2:
*to++ = *from++;
case 1:
*to++ = *from++;
} while (--n>0);
}
}
6.4.10.
exercice
crire la fonction atoi qui prend une chane de caractres et retourne un int
octal et hexadcimal
constantes caractres
crire la fonction inverse itoa
78
Cours de programmation
7.
Laurent Henocque
Le langage C++
Surcharge d'oprateur
7.1. introduction
C++ permet de dfinir des oprateurs pour toutes les classes dfinies par un programmeur
Exemples :
le type complexe, pour lequel on dfinit a + b,
le type vecteur, pour lequel on dfinit loprateur []
Attention : il est impossible de changer la prcdence des oprateurs, ni leur sens d'appariement. "=" associe de droite
gauche, alors que "<<" associe de gauche droite. Ce comportement est fig.
Attention : il est impossible de changer la syntaxe des expressions (nouveaux oprateurs, ou bien modification de
binaire en unaire par exemple)
le nom dune fonction oprateur est operator suivi du symbole adquat, avec ou sans espace
operator ==
79
Cours de programmation
Laurent Henocque
Le langage C++
80
Cours de programmation
Laurent Henocque
Le langage C++
}
matrix matrix::operator*(const matrix& a, const matrix& b)
{
matrix prod = a;
prod *=b;
return prod;
}
// erreur
81
Cours de programmation
Laurent Henocque
Le langage C++
while (cin >> x) cout << x; // conversion implicite de cin en int (son tat)
Il est conseill de ne pas abuser des conversions, qui rendent les programmes difficiles lire.
7.3.5. ambigut
Le compilateur ne ralise quun niveau de conversion automatique. Pour en avoir plusieurs, il faut les expliciter.
Les conversions utilisateur ne sont utilises que sil est impossible de faire autrement. Si une conversion standard
permet de traiter lappel, elle est utilise.
7.4. littraux
On ne peut dfinir des littraux de classes.
Mais on peut invoquer les constructeurs pour des types de base.
Ainsi : complex(1,2) peut tre considr comme une constante littrale de la classe complex.
Si le constructeur est inline, une expression lincluant ne comportera pas dappel de fonction supplmentaire.
7.7. indexation
Largument supplmentaire (index) de loprateur dindexation peut tre de nimporte quel type. On peut lutiliser
pour des dictionnaires, dont lindex est directement une chane de caractres.
82
Cours de programmation
Laurent Henocque
Le langage C++
7.9. indirections
l'oprateur -> est dfini comme un oprateur postfixe unaire.
class Ptr {
//
X* operator->();
}
void f (Ptr p){
p->m = 7; // (p.operator->())->m = 7;
Cet oprateur sert calculer un pointeur sur un objet. Lorsqu'on utilise la version habituelle de la notation ->, un nom
de membre est obligatoire aprs.
X* x = p->; // erreur
X* x = p.operator->(); // ok
{return p;
Y& operator*()
compteur++;}
Y& operator[](int i)
{return p[i];compteur++;}
};
83
Cours de programmation
Laurent Henocque
Le langage C++
//prfixe
T *operator++(int);
T *operator--();
//prfixe
T *operator--(int);
T &operator*();
//postfixe
//postfixe
//prfixe
}
void f(T t) {
T v[200];
CheckedPtrToT p(v,200);
p--;
// p.operator--(1);
*p = t;
++p;
// p.operator*() = t;
// erreur
// p.operator++();
*p = t;
// p.operator*() = t;
// ok
84
Cours de programmation
Laurent Henocque
Le langage C++
string ();{
p = new srep;
}
string (const string &from){
from.p->n++;
p = from.p;
}
// et les oprateurs ==, !=, =
}
1.m2();
f1(1);
// erreur : impossible
f2(1);
// ok f2(X(1))
f3(1);
// ok f3(X(1))
85
Cours de programmation
Laurent Henocque
Le langage C++
7.13. avertissement
L'utilisation abusive des oprateurs peut conduire des programmes illisibles.
L'utilisation d'oprateurs contre emploi aussi :
int operator+(int a, int b) {return a - b;}
86
Cours de programmation
8.
Laurent Henocque
Le langage C++
Templates
8.1. introduction
Les patrons servent dfinir des types, ou des oprations, utilisant ou s'appliquant des types fournis comme
paramtres
Ce mcanisme s'appelle la gnricit
On peut ainsi dfinir des listes de "n'importe quoi", et plus gnralement des classes "conteneurs de n'importe quoi".
L'objectif est de garder la vrification de type, et les performances
Le principe consiste dcrire des schmas de programmes, qui peuvent ensuite tre complts par les fragments
manquants, la demande.
La simple utilisation d'un patron provoque la cration des programmes ncessaires.
8.2.1. utilisation
Ce template s'utilise ensuite ainsi :
stackOf<char> sc(100);
stackOf<int> si(30);
On peut galement avoir des classes gnriques dont les fonctions ne sont pas inline, mais les compilateurs balbutient
encore un peu dans ce domaine
87
Cours de programmation
Laurent Henocque
Le langage C++
Noter dans le second cas que la rptition du paramtre de type est optionnelle
//ajout en tte
//ajout en fin
slink *get();
};
class name : public slink {
char *n;
//
};
template<class T>
class listOf : private list {
public:
void insert(T* a) {list::insert(a);}
T *
}
void f(char *s){
listOf<name> ln;
ln.insert(new name(s));
name *n = ln.get();
avantages :
typage sr
88
Cours de programmation
Laurent Henocque
Le langage C++
pas de surcot
pas de rplication de code
possibilit de cacher le code source de list l'utilisateur
une liste intrusive est optimale en temps et en mmoire
inconvnients :
pas possible de raliser des listes croises
slist<int>l1;
slist<int>l2;
l1.insert(i);
l2.insert(i); //le mme i sur deux listes
}
89
Cours de programmation
Laurent Henocque
Le langage C++
8.3.4. principe
Ne pas utiliser de rfrences comme arguments de templates : ex : slist<int&>
Cela peut provoquer des erreurs l'expansion du patron
public:
void insert(slink *a);
void append(slink *a);
slink *get();
void clear(){last = 0;}
list()last(0){}
list(slink *a)last(a->next=a){}
friend class listIter;
}
typedef void (*PFV) (const char *);
PFV setListErrorHandler(PFV f) {
PFV old = listErrorHandler;
listErrorHandler = f;
return old;
}
void defaultListErrorHandler(const char *s) {
assert(0);
90
Cours de programmation
Laurent Henocque
Le langage C++
}
PFV listErrorHandler = &defaultListErrorHandler;
8.3.8. itration
class listIter {
slink *e;
list *l;
//lment courant
//liste courante
public:
listIter(list&_l):l(&_l),e(l->last){}
inline slink* operator()();
}
slink* listIter::operator()(){
slink *ret = e ? e->next : 0;
if (ret == l->last) e = 0;
return ret;
}
template<class T> class IslistIter; //dclaration pralable
template<class T> class Islist {
//intrusive
//non intrusive
91
Cours de programmation
Laurent Henocque
Le langage C++
public:
IslistIter(Islist<T>& l):listIter(l){}
T* operator()(){
return ((Tlink<T>*)listIter::operator()())->info;
}
}
void f(name *p){
Islist<name> l1;
Slist<name> l2;
l1.insert(p);
l2.insert(p);
IslistIter<name> it1(l1);
const name *p;
while (p = it1()) { // do something }
}
92
Cours de programmation
Laurent Henocque
Le langage C++
8.4.1. exemple
On peut aussi implanter une classe de vecteurs triables
template<class T> void sort(sortableVect<T>&) {
/* trie en ordre croissant */
unsigned n = v.size();
for (int i = 0 ; i<n-1 ; i++)
for (int j = n-1 ; i<j ; j--)
if (v.lessThan(v[j],v[j-1])) swap (v[j],v[j-1]);
}
template<class T> sortableVect:public vect, public comp<T> {
public:
sortableVect(int s):vect(s){}
}
template<class T> class comp {
static int lessthan(T&a,T&b) {return a<b;}
}
class comp<char *> {
static int lessthan(T&a,T&b) {return strcmp(a,b)<0;}
}
93
Cours de programmation
Laurent Henocque
Le langage C++
f() {
T *p = new(A::operator new(sizeof(T))) T;
94
Cours de programmation
9.
Laurent Henocque
Le langage C++
En cas de situation exceptionnelle (i.e. sortant du cadre prvu par l'algorithme), le programmeur se trouve devant
plusieurs alternatives, nonquivalentes en cot de conception et de codage :
1 : terminer le programme en indiquant le lieu de l'erreur (assert())
2: retourner une valeur reprsentant l'erreur, qui doit tre propage, et traite, par toutes les fonctions appelantes
3: continuer dans un tat invalide (avec ou non affichage de message)
4: provoquer un "longjump" jusqu' un point o l'erreur peut tre traite (et un tat valide reconstruit)
C++ offre une solution lgante et performante au problme de la prise en compte des exceptions
9.2.1. utilisation
void f()
{
try {
g();
} catch (vector::range r) {
cout << "bad index" << r.index << endl;
95
Cours de programmation
Laurent Henocque
Le langage C++
} catch (allocator<char>::exhausted)
}
}
La classe exception peut aussi tre globale, i.e. non intgre dans la classe qui provoque l'exception
On peut utiliser l'hritage dans des classes d'exceptions et profiter des fonctions virtuelles
C'est utile car cela permet de traiter toutes les exceptions, y compris celles venir
class matherr {};
class overflow : public matherr {};
class underflow : public matherr {};
class zerodivide : public matherr {};
try { }
catch (overflow) {
96
Cours de programmation
Laurent Henocque
Le langage C++
Les gestionnaires sont essays dans l'ordre, et cet ordre est donc opportun
Le compilateur connat la hirarchie des classes et peut donc signaler des erreurs : exception masque et donc jamais
gre par exemple.
catch(...)signifie : intercepter n'importe quelle exception
try { // qqchose
} catch (...){
// autre chose
throw; //relance l'exception exacte d'origine
}
97
Cours de programmation
Laurent Henocque
Le langage C++
Si le constructeur de bb lance une exception, celui de aa ayant t termin, le destructeur de aa sera appel, mais pas
celui de bb.
variante sre :
template<class T>class arrayOf{
T *p;
arrayOf(int s){p = new T[s];}
arrayOf(){delete[] p;}
operator T* (){return p;}
}
struct X{
arrayOf<int> p;
X(int s) : p(s){init()};
X() {}
}; // si init lance une exception, p est libr
Le code d'un constructeur n'est pas appel si new ne parvient pas allouer assez d'espace pour l'objet.
98
Cours de programmation
Laurent Henocque
Le langage C++
//remet
throw;
//relance
}
set_new_handler (oldnh);
//remet
99
Cours de programmation
Laurent Henocque
Le langage C++
set_unexpected (PFV);
class STC {
PFV old;
STC(PFV f) : old(set_unexpected(f)) {}
STC(){set_unexpected(old);}
};
void rethrow () { throw;}
f_qui_laisse_passer()
{
STC(&rethrow);
f();
}
100
Cours de programmation
Laurent Henocque
Le langage C++
9.8.
101
Cours de programmation
Laurent Henocque
Le langage C++
10. Flots
10.1. introduction
Les flots sont accessibles par l'interface "iostream.h"
Les noms de fonction sont surchargs pour tous les types souhaits
Des oprateurs sont dfinis (<< et >>)
10.2. sorties
put(cerr, "x = ");
put(cerr, x);
put(cerr, "\n");
// notation directe :
cerr << "x = " << x << "\n";
cout << a * b + c << "\n"; //prcdence assez basse de <<
class ostream : public virtual ios {
//
public :
ostream& operator<<(const char *);
ostream& operator<<(char);
ostream& operator<<(short i){return *this<<int(i);;
ostream& operator<<(int);
ostream& operator<<(long);
ostream& operator<<(float);
ostream& operator<<(double);
ostream& operator<<(const void *);//tous les pointeurs
};
10.2.1.
class complex{
//
friend ostream& operator<<(ostream& o, complex&c);
102
Cours de programmation
Laurent Henocque
Le langage C++
}
ostream& operator<<(ostream& o, complex&c) {
return o << '(' << c.re << ',' << c.im << ')';
}
//utilisation :
main(){
complex c(1,2);
cout << "le complexe c vaut " << c << endl;
}
10.3. entres
class istream : public virtual ios {
//
public :
istream& operator<<(char *);
istream& operator<<(char&);
istream& operator<<(short&);
istream& operator<<(int&);
istream& operator<<(long&);
istream& operator<<(float&);
istream& operator<<(double&);
};
// ide du code :
istream& operator<<(T& tvar) {
//sauter les espaces
//lire un "T" dans tvar
return *this
}
int readints (Vector<int>& v){
for (int i = 0;i<v.size ; i++) {
if (cin>>v[i++]) continue; //converteur implicite en int
return i;
}
//autres traitements
}
//autres mthodes de la classe istream :
istream& get (char &c);
103
Cours de programmation
Laurent Henocque
Le langage C++
10.3.1.
int isalpha(char);
int isupper(char);
int islower(char);
int isxdigit(char);
int isspace(char);
int iscntrl(char);//0->31, 127
int ispunct(char);//aucun des prcdents
int isalnum(char);//alpha ou digit
int isprint(char);//affichable ascii ' ' .. ''
int isgraph(char);//alnum ou ispunct
int isascii(char);//compris entre 0 et 127
//toutes sauf isascii sont values par accs direct ds tableau
//donc plus efficaces que des comparaisons
10.3.2.
tats du flot
10.3.3.
104
Cours de programmation
Laurent Henocque
Le langage C++
char c = 0;
s >> c;
if ( c == '(' ) {
s >> re >> c;
if ( c == ',' ) {
s >> im >> c;
} // pas de else
if (c != ')') {
s.clear (ios::badbit); //
} else {
s.putback(c);
s >> re;
}
if (s) a = complex (re,im);
return s;
}
int width()const;
//retourne la longueur
char fill(char);
char fill()const;
long flags(long);
long flags()const;
long setf(long setbits, long field);
long setf(long);
long unsetf(long);
int precision (int);
int precision ()const;
void clear (int i = 0);
int rdstate()const, eof()const, bad()const, fail()const, good()const;
105
Cours de programmation
10.4.1.
Laurent Henocque
Le langage C++
liaison de flots
main () {
char s[50];
cout << "passwd :";
// grce tie, on peut omettre ici cout.flush();
cin >> s;
}
//
cin.tie(0); // permet de supprimer le lien
10.4.2.
champs de sortie
Le paramtre width (0 par dfaut) spcifie le nombre de caractres utiliser pour la prochaine (seulement) sortie
numrique ou de chane de caractres. La valeur 0 signifie : autant que ncessaire.
Le paramtre fill (espace par dfaut) est le caractre utilis pour combler
cout.width(4);
cout.fill(*);
cout << '(' << 12 << ')';
// produit :
(**12)
10.4.3.
tat du format
La classe ios maintient un paramtre (flags) dcrivant les diffrents paramtres de format.
class ios {
public :
enum {
skipws=01, //sauter les sparateurs en entre
//remplissage :
left=02,
right=04,
//avant la valeur
//aprs la valeur
internal=08,
//base entire :
dec = 020,
oct = 040,
hex = 0100,
showbase = 0200,
//montrer la base
106
Cours de programmation
Laurent Henocque
Le langage C++
//ddd.dd
};
};
//utilisation :
mystream.flags(mystream.flags() | ios::showbase);
//ou son quivalent :
mystream.setf(ios::showbase);
10.4.4.
10.4.5.
manipulateurs
Il est parfois ncessaire de procder des oprations sur les flots autres que des entres sorties, au milieu de ces
dernires. Ex :
cout << x; cout.flush(); cout<<y;
107
Cours de programmation
Laurent Henocque
Le langage C++
//
public :
ostream& operator<<(ostream& (*)(ostream&));
10.4.6.
manipulateurs de istream
10.4.7.
utilisation de patrons
On peut dfinir un patron pour prvoir des structures de manipulateurs pour tous les types, autres qu'entiers :
template<class T> class OMANIP {
T i;
ostream& (*f)(ostream&,T);
public:
OMANIP(ostream& (*_f)(ostream&,T),T _i) : f(_f), i(_i){}
108
Cours de programmation
Laurent Henocque
Le langage C++
Les templates OMANIP, IMANIP et SMANIP (pour ios) sont dfinis dans <iomanip.h>
10.4.8.
Passer un objet plutt qu'appeler une fonction est une technique intressante, mme dans d'autres domaines que les
entres sorties.
Un objet est cr, puis pass n'importe o, et utilis comme une fonction.
Cela permet de partager les dtails d'excution entre l'appel et l'appelant.
10.4.9.
10.4.10.
membres de ostream
On peut avoir un accs direct une position d'un fichier, ds qu'il est li un ostream :
class ostream : public virtual ios {
ostream& flush();
ostream& seekp(streampos);
ostream& seekp(streamoff,seek_dir);
streampos tellp();
109
Cours de programmation
Laurent Henocque
Le langage C++
};
10.4.11.
membres de istream
On peut avoir un accs direct une position d'un fichier, ds qu'il est li un istream :
class istream : public virtual ios {
int peek(); // consulte le prochain caractre sans lire
istream& putback(char c);
istream& seekg(streampos);
istream& seekg(streamoff,seek_dir);
streampos tellg();
};
1<<0;//ouvert en entre
out
1<<1;//ouvert en sortie
ate
1<<2;//ouvre et va a la fin
app
1<<3;//ajoute
trunc
nocreate
noreplace
};
};
// exemple : copie d'un fichier dans un autre
main(int argc, char **argv){
110
Cours de programmation
Laurent Henocque
Le langage C++
assert(argc == 3);
ifstream inp(argv[1]);
assert(inp);
ofstream out(argv[2]);
assert(out);
char c;
while (inp.get(c) && out.put(c));
assert(inp.eof() && !out.bad());
}
10.5.1.
paramtrage
Un ofstream est ouvert en criture par dfaut, un ifstream en lecture. On peut aussi paramtrer cette ouverture :
ofstream out(name, ios::out|ios::nocreate);
fstream dictionary("dict.text", ios::in|ios::out);
10.5.2.
A l'arrt du programme, les flots cin, cout et cerr sont automatiquement ferms
10.5.3.
10.5.4.
mise en tampon
Les entres sorties utilisent des mcanismes de tampons distincts suivant que le type de flot est un fichier, ou un
tableau de caractres. Le mcanisme de leur prise en compte tire profit de la possibilit d'avoir des fonctions de dbordement
(overflow et underflow) virtuelles.
10.6. entres/sorties C
On peut entremler des appels aux fonctions d'entre sortie C sur une base ligne ligne. (au niveau des caractres on
peut avoir des problmes de portabilit).
Certaines implantations de C++ demandent d'appeler une fonction membre static de la classe ios pour travailler avec
des fonctions C:
Ecole Suprieure dIngnieurs de Luminy / dpartement ES2I, Marseille
111
Cours de programmation
Laurent Henocque
Le langage C++
ios::sync_with_stdio ();
112
Cours de programmation
Laurent Henocque
Le langage C++
113