301
C vers C++ version support : 2.0

Passer du langage C au langage C++

Embed Size (px)

Citation preview

Page 1: Passer du langage C au langage C++

C vers C++

version support : 2.0

Page 2: Passer du langage C au langage C++

Introduction

• C++ a été développé dans les années 1980 parBjarne Stroustrup

• http://www2.research.att.com/~bs/homepage.html

• C++ est un langage normalisé par l'ISO

ISO/CEI 14882:1998– ISO/CEI 14882:1998

– ISO/CEI 14882:2003

– ISO/CEI 14882:2011 (C++11)

– ISO/CEI 14882:2014 (mise à jour de la norme)

• C++ est un autre langage que C

antislashn.orgC vers C++ 2

Page 3: Passer du langage C au langage C++

Introduction

• Principales fonctionnalités ajoutées par rapport au langage C– déclaration reconnue comme une instruction (repris en C99)– opérateurs new et delete– type de donnée bool– mot clé const (repris en C99)– espaces de nom– classes et tout ce qui est lié à la POO– classes et tout ce qui est lié à la POO– surcharge des opérateurs– gestion des exceptions– identification des types à l'exécution

• RTTI : run-time type identification

– commentaire // (repris en C99)– fonction inline (repris en C99)– paramètres par défaut dans les fonctions– les références

antislashn.orgC vers C++ 3

Page 4: Passer du langage C au langage C++

Hello, world

• L'exemple incontournable

#include <iostream>

using namespace std;

int main(int argc, char *argv[]){

inclusion du fichierd'entête, le ".h" n'est pasnécessaire (sauf pour C)

utilisation d'espace denommage pour éviter lescollisions de nom

type de retourobligatoire

hello.cpp

antislashn.orgC vers C++ 4

{cout << "Hello, world" << endl;system("PAUSE");return EXIT_SUCCESS;

}

objet de typeostreamreprésentant leflux de sortie opérateur

d'insertion

return facultatifsi absent un return 0 esteffectué

Page 5: Passer du langage C au langage C++

Programmation orientée objet

• L'objet– propriétés (variables de l'objet)– méthodes (fonctions manipulant les variables de l'objet)

• Concepts de base– encapsulation

• il n'est pas possible d'accéder aux données de l'objet• il n'est pas possible d'accéder aux données de l'objet– uniquement par l'intermédiaire des méthodes

– classe• généralisation de la notion de type• structure de données + fonctions

– héritage• permet de créer une nouvelle classe sur une classe existante

– polymorphisme• possibilité de traiter de la même manière des objets de type différents

antislashn.orgC vers C++ 5

Page 6: Passer du langage C au langage C++

Conventions de nommage

• Utilisez des noms de fonction, de variable quipermettent une auto-documentation du code

• Attention aux conventions de pré-fixage des nomsde variables par leur type

• int intNb;

– que devient le préfixe si le type vient à évoluer ?

• int est remplacé par long, pour rester cohérent il faut queintNb devienne longNb

antislashn.orgC vers C++ 6

Page 7: Passer du langage C au langage C++

Type C++

• Les types du langage C sont repris par C++– entiers (nb octets donné à titre indicatif)

• char : 1 octet• short int (ou short) : 2 octets• int : 4 octets• long int (ou long) : 4 octetslong int (ou long) : 4 octets• long long : 8 octets• peuvent être signed, ou unsigned

– types flottants• float : 8 bits exposants, 23 bits mantisse (4 octets)• double : 11 bits exposants, 52 bits mantisse (8 octets)• long double : 15 bits exposants, 64 bits mantisse (12 octets)

– type booléen• bool : valeurs true ou false

antislashn.orgC vers C++ 7

Page 8: Passer du langage C au langage C++

C++11 – pointeur NULL

• Le mot clé nullprt a été ajouté commeconstante du langage

– constante de type nullptr_t

• non convertible vers un entier

• convertible vers void*• convertible vers void*

– assignable à tout type de pointeur• en C++ il est interdit d'assigner un void* à un pointeur

d'un type différent

antislashn.orgC vers C++ 8

Page 9: Passer du langage C au langage C++

Quelques différences avec C

• La bibliothèque standard C++ définit de nouvellesclasses et templates.

– nous utiliserons régulièrement

• la classe string

– représente une chaîne de caractères– représente une chaîne de caractères

• la classe vector

– peut-être vu comme un tableau dynamique

– le type des éléments doit être précisé lors de la déclaration

• ces classes seront vues plus en détail plus tard

antislashn.orgC vers C++ 9

Page 10: Passer du langage C au langage C++

Quelques différences avec C

• Exemple d'utilisation de string et vector

#include <iostream>#include <vector>#include <string>

using namespace std;

int main(){

vector-string.cpp

inclusionsnécessaires

construction

antislashn.orgC vers C++ 10

int main(){string nom = "toto";vector<int> v;

for(int i=0 ; i < 5 ; i++)v.push_back(i);

cout << nom << endl;for(int i=0 ; i < v.size() ; i++)

cout << v[i] << " ";cout << endl;

}

ajout dynamiqued'éléments

d'un vecteur deint

Page 11: Passer du langage C au langage C++

Affichage à l'écran

• Opérateur d'insertion <<

– surcharge de l'opérateur de décalage à gauche

• un même symbole peut désigner plusieurs opérateursdistincts

– l'opérande de droite est envoyé vers le flux– l'opérande de droite est envoyé vers le flux

– opérateur associatif de droite vers la gauche

• permet d'enchainer les affichages

– de nombreuses options et opérateurs permettent deformater la sortie

antislashn.orgC vers C++ 11

Page 12: Passer du langage C au langage C++

Lecture au clavier

• Opérateur d'extraction >>– surcharge de l'opérateur de décalage vers la droite

• cin représente l'entrée standard– instance de la classe istream

cout << "Entrez un nombre : ";cin >> nb;

– instance de la classe istream

– l'opérateur >> est associatif de gauche à droite

• un séparateur quelconque (espace, tabulation,…) est utilisépour l'analyse

– n'est pas recueilli

– de nombreuses options et opérateurs sont disponibles

antislashn.orgC vers C++ 12

cin >> nb >> nom;

Page 13: Passer du langage C au langage C++

C++11 – Inférence de type

• Nouvelle sémantique pour le mot clé auto

– indiquait la classe de stockage

• comportement par défaut

• auto était rarement utilisé

– depuis C++11 auto prend la place du type dans la– depuis C++11 auto prend la place du type dans ladéclaration de variable

• le type sera alors celui de la rvalue

• la variable de type auto doit donc être initialisée lors de ladéclaration

antislashn.orgC vers C++ 13

Page 14: Passer du langage C au langage C++

C++11 – Inférence de type

• Le mot clé decltype permet de typer unevariable à partir du type d'une expression

int number = 1;auto y = number;decltype(y) z;

y et z seront de type int

• auto peut être utilisé pour le type de retourd'une fonction

– le type est précisé après la parenthèse fermante

antislashn.orgC vers C++ 14

int aa;auto foo() -> decltype(aa){

return aa++;} le type de retour sera int

Page 15: Passer du langage C au langage C++

C++11 – boucle "foreach"

• L'instruction for permet de parcourir unintervalle

– tableau, conteneurs de la STL définissant les fonctionsmembres begin() et end()

antislashn.orgC vers C++ 15

int tab[5] = {1, 2, 3, 4, 5};for (int &x: tab) {

x *= 2;}

Page 16: Passer du langage C au langage C++

C++11 – type array

• Type std::array<TYPE,TAILLE>

– inclure <array>

• Possède des méthodes

– size(), front(), back(), at(), empty(), …

– les crochets [] sont toujours utilisables

antislashn.orgC vers C++ 16

const int TAILLE = 5;

array<int,TAILLE> tab = {1,2,3,4,5};

for(int nb : tab){cout << nb << endl;

}

Page 17: Passer du langage C au langage C++

C++11 – énumérations fortement typées

• Utilisation de enum class ou enum structà la place de enum

– pas de conversion implicite vers le type int

• conversion explicite seulement

– accès aux éléments par l'opérateur de portée ::– accès aux éléments par l'opérateur de portée ::

antislashn.orgC vers C++ 17

enum class State{STOP,START};State s = State::STOP;

Page 18: Passer du langage C au langage C++

Fonctions inline

• Une fonction inline donne la possibilité à C++d'insérer le code sans créer de fonction

– pas de création de fonction, pas de copie sur la pile

– exemple :inline int carre(int x) {return x*x;}inline int carre(int x) {return x*x;}

– évite les effets de bords des définitions de macro du C#define carre(x) ((x)*(x))

– n'est qu'une requête au compilateur, celui-ci peut l'ignoreret créer une vraie fonction

– ne peut pas faire l'objet d'une compilation séparée

– ne peut pas être manipulée par un pointeur vers fonction

antislashn.orgC vers C++ 18

Page 19: Passer du langage C au langage C++

Fonctions inline

• En fonction des réglages du compilateur, lesfonctions peuvent être inline automatiquementou pasinline int max(int a, int b){return a>b?a:b;}

int main(void)

antislashn.orgC vers C++ 19

int main(void){

int i,j,k;cin >> j >> k;i = max(j,k);cout << i << endl;

}

_TEXT SEGMENT?max@@YAHHH@Z PROC; max, COMDAT

; _a$ = ecx; _b$ = eax

; 5 : int max(int a, int b){return a>b?a:b;}

00000 3b c8 cmp ecx, eax00002 7e 02 jle SHORT $LN4@max00004 8b c1 mov eax, ecx

$LN4@max:00006 c3 ret 0

?max@@YAHHH@Z ENDP; max

Page 20: Passer du langage C au langage C++

Fonctions inline

• Sous Visual Studio

– sur le projet faire clic droit puis propriétés

antislashn.orgC vers C++ 20

Page 21: Passer du langage C au langage C++

Les références

• Nouveauté notable de C++ par rapport à C

– ne doit pas être confondue avec la notion de pointeur

– le passage par adresse (contenu d'un pointeur) n'estpas le passage par référence

– une référence est un alias d'un objet en mémoire– une référence est un alias d'un objet en mémoire

– syntaxe :type & identificateur = expression;

antislashn.orgC vers C++ 21

int main(){int i = 30;int &ri = i;

ri += 10;cout << i << " == " << ri << endl;cout << "@i = " << &i << endl;cout << "@ri = " << &ri << endl;

} reference.cpp

Page 22: Passer du langage C au langage C++

Les références

• Une référence doit être initialisée lors de sadéclaration

– avec un objet (expression devant être une lvalue)

• int &i = 10; n'est pas valide– dépend du compilateur et version de C++– dépend du compilateur et version de C++

• const int &i = 10; est valide

– on ne peut pas déclarer un tableau de références• int i, j;

int &tab[] = {i,j}; est illégal

– en pratique les références sont utilisées dans le cadrede passage de paramètres et retour de fonction

antislashn.orgC vers C++ 22

Page 23: Passer du langage C au langage C++

Passage d'arguments par référence

• En C les arguments sont passés par valeur– il y a création sur la pile d'une nouvelle variable

– copie de l'argument passé• dans le cas d'un pointeur il y a bien copie du contenu du pointeur,

c'est-à-dire de l'adresse de l'objet pointé

– la valeur initiale de la variable passée n'est pas– la valeur initiale de la variable passée n'est pasaffectée par les modification dans la fonction

• Le passage par référence crée un nouveau nompour la variable passée à la fonction– les modifications dans la fonction impacterons la

valeur de la variable initiale

antislashn.orgC vers C++ 23

Page 24: Passer du langage C au langage C++

Passage d'arguments par référence

• La fonction classique d'échange permet d'illustrerle passage par référence

void echanger(int &i, int &j){

int t = i;i=j;j=t;

}

reference-echanger.cpp

– les valeurs de a et b ont bien été échangées

antislashn.orgC vers C++ 24

}int main(){

int a = 10;int b = 30;cout << "Avant a == " << a << " et b == " << b << endl;echanger(a,b);cout << "Apres a == " << a << " et b == " << b << endl;

}

Page 25: Passer du langage C au langage C++

Retour de référence

• En C une fonction de la forme

– retourne la valeur de x

int f(){

...return x;

}

– retourne la valeur de x

• il y a création sur la pile d'une variable à laquelle estaffectée la valeur de x

• l'expression f() est une rvalue, non pas une lvalue

– on ne peut pas écrire

f() = expression;

antislashn.orgC vers C++ 25

Page 26: Passer du langage C au langage C++

Retour de référence

• En C++ une fonction peut retourner une référence

– dans ce cas l'expression f() est une référence vers la

int &f(){

...return x;

}

– dans ce cas l'expression f() est une référence vers lavariable x

• c'est-à-dire une lvalue– on peut écrire

f() = expression;

• de nombreuses fonctions ou templates C++ retournent desréférences

– operator<<, operator>>, etc…

antislashn.orgC vers C++ 26

Page 27: Passer du langage C au langage C++

Retour de référence

• Exemple

int & augmenter(int &x){

x += 10 ;return x;

}int main(){

int i = 5;

retour-reference.cpp

– l'expression augmenter(i) est une référence pourla variable i du main

• i vaudra 30

antislashn.orgC vers C++ 27

int i = 5;augmenter(i) += 15;cout << i << endl;system("PAUSE");

}

Page 28: Passer du langage C au langage C++

Retour de référence

• Ne pas retourner une référence à une variablelocale d'une fonction– la variable locale est créée sur la pile et sa durée de

vie est celle de la fonction• comme il ne faut pas retourner l'adresse d'une variable

locale lorsque l'on travaille par pointeur• comme il ne faut pas retourner l'adresse d'une variable

locale lorsque l'on travaille par pointeur

• Attention aux conversions de type– si i avait été de type char l'appel de la fonction aurait

généré une conversion de type, donc une variabletemporaire aurait été créée sur la pile qui n'est pas lavariable i

antislashn.orgC vers C++ 28

Page 29: Passer du langage C au langage C++

Surcharge des fonctions

• C++ permet de surcharger les fonctions

– un même nom de fonction peut-être associé àplusieurs fonctions

– le compilateur génère plusieurs fonctions de nomsdifférents en tenant compte du type des paramètresdifférents en tenant compte du type des paramètres

• la signature de la fonction

• le type de retour n'est pas utilisé

• le modificateur const est utilisé

– le choix de la fonction à appeler est déterminé par letype des arguments

antislashn.orgC vers C++ 29

Page 30: Passer du langage C au langage C++

Surcharge des fonctions

• Le compilateur va générer 4 fonctions– afficher_Fi, afficher_Fc, afficher_Fd,afficher_FPc

• F pour fonction, P pour pointeur, R pour référence, C pourconstant

génèrerait– f(const char &) génèrerait f_FRCc

antislashn.orgC vers C++ 30

void afficher(int i){ cout << "int : " << i << endl; }

void afficher(char c){ cout << "char : " << c << endl; }

void afficher(double d){ cout << "double : " << d << endl; }

void afficher(char * s){ cout << "string : " << s << endl; }

surcharge-fonctions.cpp

Page 31: Passer du langage C au langage C++

Surcharge des fonctions

• Appel de fonctions C par un programme C++

– soit une fonction C int f(int); est définie dansune librairie C

– la simple déclaration de son prototype est insuffisante

• le compilateur lui donnera un nom différent, tenant compte• le compilateur lui donnera un nom différent, tenant comptedes paramètres

• l'éditeur de lien ne pourra pas la retrouver

– la déclaration doit être faite par• extern "C" int f(int);

• si plusieurs fonctions :– extern "C" {déclarations et inclusions}

antislashn.orgC vers C++ 31

Page 32: Passer du langage C au langage C++

Surcharge des fonctions

• Pour choisir la fonction surchargée le compilateur utilise uncertain nombre de règles1. il recherche une version avec correspondance exacte de type

entre les arguments et les paramètres2. il essaie d'appliquer les règles habituelles de promotion

numérique3. il essaie d'appliquer les règles de conversion standard sur les3. il essaie d'appliquer les règles de conversion standard sur les

pointeurs et références (classes et classes dérivées)4. il essaie d'appliquer les règles de conversion définies par le

développeur (vues plus loin)5. il vérifie s'il existe une version à un nombre variable

d'arguments

• Au cours de ces étapes, si une ambigüité est détectée lecompilateur lève une erreur

antislashn.orgC vers C++ 32

Page 33: Passer du langage C au langage C++

C++11 – fonctions lambda

• fonction anonyme

– fonction qui n'a pas de nom

– peut-être passée comme argument

• par exemple à la fonction std::for_each, à la place d'unfoncteurfoncteur

– syntaxe :[](paramètres) -> return_type { corps; }

• [] : captures

• si return_type n'est pas précis il est déduit par lecompilateur

antislashn.orgC vers C++ 33

Page 34: Passer du langage C au langage C++

C++11 – fonctions lambda

• Exemple

vector<int> nombres = {0,1,2,3,4,5,6,7,8,9};

for_each(nombres.begin(), nombres.end(), [](int element) {cout << element << endl;

liste d'initialisation C++11

antislashn.orgC vers C++ 34

});

lambda

[](int a, int b) -> int{ return a+b; };

type de retour

Page 35: Passer du langage C au langage C++

C++11 – fonction lambda

• Il est possible d'affecter une lambda à unevariable

– de type std::function

• adaptateur générique de fonction permettant d'appeler unecible appelablecible appelable

– cible pour laquelle operator() est défini

– on fournit alors le type de retour et la liste des arguments

» void s'il n'y a pas de type de retour

• ou de type auto

antislashn.orgC vers C++ 35

std::function<int (int,int)> add1 = [](int a, int b){ return a+b; };auto add2 = [](int a, int b){ return a+b; };

type de retour suivi du type desparamètres

Page 36: Passer du langage C au langage C++

C++11 – fonctions lambda

• Closure

– une fermeture est une fonction qui capture desvariables à l'extérieur de celle-ci

– il faut préciser les variables à capturer entre []

– la capture est effectuée– la capture est effectuée

• par référence– les éventuelles modifications affecterons la variable capturée

• par valeur– c'est une copie de la variable capturée, les modifications

n'affecterons pas la variable capturée

antislashn.orgC vers C++ 36

Page 37: Passer du langage C au langage C++

C++11 – fonctions lambda

• Exemples

int somme = 0;auto add = [&somme](int a, int b){ somme=a+b; };

antislashn.orgC vers C++ 37

int somme = 0;auto add = [somme](int a, int b){ somme=a+b; };

Page 38: Passer du langage C au langage C++

C++11 – fonctions lambda

• Résumé de la syntaxe de capture– [] : pas de variable externe

– [i,&j] : i capturée par valeur, j par référence

– [&] : toutes les variables externes sont capturées parréférenceréférence

– [=] : toutes les variables externes sont capturées parvaleur

– [&,x] : x est capturée par valeur, les autresvariables externes sont capturées par référence

– [=,&x] : x est capturée par référence, les autresvariables externes sont capturées par valeur

antislashn.orgC vers C++ 38

Page 39: Passer du langage C au langage C++

Arguments par défaut

• Il est possible d'affecter une valeur par défaut àtout ou partie des paramètres d'une fonction

void afficher(int i, int b=0, int c=3){…}

– l'affectation par défaut peut remplacer certainessurcharges explicites d'une fonction

antislashn.orgC vers C++ 39

Page 40: Passer du langage C au langage C++

Opérateur de portée ::

• L'opérateur de portée :: permet d'utiliser unevariable globale masquée par une variable locale

int x = 10;int main(){

int x = 20;cout << "x local == " << x <<endl;

antislashn.orgC vers C++ 40

cout << "x local == " << x <<endl;cout << " x global == " << ::x << endl;

}surcharge-fonctions.cpp

Page 41: Passer du langage C au langage C++

Ordres des déclarations

• Contrairement au C, les déclarations peuvent êtreeffectuées lors de la première utilisation d'unevariable

int main(){

int x = 10;

x est visible dans toute lafonction main

i est déclaré seulement pour

antislashn.orgC vers C++ 41

int x = 10;for(int i = 0 ; i<10 ; i++){cout << i << endl;}if(int i=x-11 > 0)

cout << "i > 0" << endl;else

cout << "i <= 0" << endl;cout << i << endl;

}

i est déclaré seulement pourle bloc for

i est déclaré seulement pourle bloc if - else

erreur de compilation carpas de déclaration pour ce i

declarations.cpp

Page 42: Passer du langage C au langage C++

Allocation dynamique de mémoire

• En C l'allocation de mémoire est effectuée par unmalloc, la libération de mémoire par free

• En C++ l'allocation de mémoire est effectuée parnew, la libération par delete

antislashn.orgC vers C++ 42

int main(){

int *pi;int *ti;pi = new int;ti = new int[50];

delete pi;delete [] ti;

}

affectation de l'adressed'un int

affectation de l'adressed'un tableau de 50 int

libération pour un int

libération pour un tableaude int

new-simple.cpp

Page 43: Passer du langage C au langage C++

Allocation dynamique de mémoire

• L'opérateur new permet d'initialiser un objet detype défini :

int * pi = new int(10);

• Lorsque new retourne l'adresse d'une instance declasse ou de structure, cette initialisation n'estclasse ou de structure, cette initialisation n'estpossible que si un constructeur adéquat a étéprévu.

• Il n'est pas possible d'initialiser un tableau allouépar new

antislashn.orgC vers C++ 43

Page 44: Passer du langage C au langage C++

Allocation dynamique de mémoire

• Allocation à une adresse imposée

• Gestionnaire de manque de mémoire– il faut vérifier que new (comme malloc) ne retourne pas la

valeur null

int *pi;int *ti;pi = new ((int *)0X0FFF) int;ti = new (pi+10) int[50];

new-simple.cpp

valeur null

– un gestionnaire peut être mis en place pour tout retour denull par new

• le rôle de ce gestionnaire est de tenter de libérer de la mémoire– à la fin de l'exécution du gestionnaire, la main est donnée de nouveau au new

» sauf si dans le gestionnaire il y a une instruction type exit(…)

• le gestionnaire (handler) ne doit attendre aucun paramètre et neretourne rien

• l'adresse du handler est passée à la fonction set_new_handler

antislashn.orgC vers C++ 44

Page 45: Passer du langage C au langage C++

Allocation dynamique de mémoire

• Exemple de handler

void gestionnaire(){

cout << "Plus de memoire" << endl;system("PAUSE");exit(1);

}mise en place du gestionnaire

antislashn.orgC vers C++ 45

int main(){

set_new_handler(gestionnaire);int *pi;int *ti;pi = new int;ti = new int[1000000000];

delete pi;delete [] ti;

}

demande trop importante

mise en place du gestionnaire

new-handler.cpp

Page 46: Passer du langage C au langage C++

Emploi de const

• const int i = 10;

– définit une valeur qui restera constante

• i est de type const int

– en C++ le compilateur peut ne pas définir un objet enmémoiremémoire

– doit être initialisé à la définition

• par une expression constante, connue à la compilation

– un objet const est de classe static

antislashn.orgC vers C++ 46

Page 47: Passer du langage C au langage C++

Emploi de const

• int i;const int *p = &i;– p est un pointeur qui pointe sur un objet constant

• l'initialisation de p n'est pas obligatoire

– i peut être modifié directement, pas par *p• int i;int *const p = &i;int *const p = &i;– p est un pointeur constant qui pointe sur un objet i

• l'initialisation est obligatoire• p ne peut pas varier• i peut être modifié directement ou via *p

• const int * const p = &i;– p est un pointeur constant qui pointe sur un objet constant

• initialisation obligatoire• p ne peut pas varier, *p n'est pas une lvalue

antislashn.orgC vers C++ 47

Page 48: Passer du langage C au langage C++

Emploi de const

• Paramètre de type const

– si on fournit un argument de type const à une fonction, lecompilateur génère une erreur

• certains compilateurs génèrent un warning

– il faut définir le paramètre de la fonction comme const– il faut définir le paramètre de la fonction comme const

• Nous reviendrons sur le modificateur const lors del'étude des classes

antislashn.orgC vers C++ 48

void f(const int &i) { cout << i << endl; }

const int j = 20;int main(){

f(j);system("PAUSE");

}

Page 49: Passer du langage C au langage C++

Forçage de type

• En C++ il est illégal de convertir un pointeurvoid* en un autre type sans forçage explicite dutypeint *p = malloc(20);

• n'est pas légal en C++• n'est pas légal en C++

int *p = (int *) malloc(20);

• est légal en C++

antislashn.orgC vers C++ 49

Page 50: Passer du langage C au langage C++

Forçage de type

• Comme en C

– un pointeur vers un objet non constant ou vers unefonction peut être affecté à un pointeur void*

– l'adresse d'un objet constant ne peut pas être affectéà un pointeur non constant sans forçage de typeà un pointeur non constant sans forçage de type

antislashn.orgC vers C++ 50

const int j = 10;int * q1 = &j; // ILLEGALvoid *q2 = &j; // ILLEGALvoid *q3 = (int *)&j; // LEGAL mais dangereuxconst void *q4 = &j; // CORRECT

const.cpp

Page 51: Passer du langage C au langage C++

Forçage de type

• C++ introduit de nouveaux opérateurs de forçagede type :

– static_cast

– dynamic_cast

–– const_cast

– reinterpret_cast

– syntaxe :• opérateur <type> (expression);

antislashn.orgC vers C++ 51

Page 52: Passer du langage C au langage C++

Forçage de type

• static_cast– permet d'effectuer toute conversion standard, si les types sont

cohérents entre eux• type vers type• pointeur vers pointeur• référence vers référence

– ne permet pas de retirer le modificateur const– ne permet pas de retirer le modificateur const

• dynamic_cast– effectue des vérifications à l'exécution– utilisé pour le polymorphisme

• sera vu plus loin

antislashn.orgC vers C++ 52

const int i = 10;char c = static_cast <char> (3.14); // CORRECTint *p = static_cast <int *> (&i); // ILLEGALint *q = static_cast <int *> (20000); // ILLEGAL

forcage-type.cpp

on force l'adressepointée par q

Page 53: Passer du langage C au langage C++

Forçage de type

• const_cast

– permet la conversion d'une entité const en entiténon const

const int i = 10;double j = 10;int *p = const_cast <int *> (&i); // CORRECT

forcage-type.cpp

• reinterpret_cast

– permet de forcer le typage entre types différents

– ne permet pas de retirer le modificateur const

antislashn.orgC vers C++ 53

int *p = const_cast <int *> (&i); // CORRECTint q = const_cast <int> (j); // ILLEGAL

const int i = 10;int *p = reinterpret_cast <int *> (&i); // ILLEGALint *q = reinterpret_cast <int *> (2000); // CORRECT

forcage-type.cpp

Page 54: Passer du langage C au langage C++

Structure

• C++ conserve la notion de structure du C– en C++ la structure réunie des données et des

fonctions membres• la syntaxe d'accès reste la même :

– point . pour un accès direct

– flèche -> pour un accès par pointeur– flèche -> pour un accès par pointeur

– trois niveaux de visibilité sont prévus• public : visibilité en tout point du programme

– visibilité par défaut sur les structures

• private : visibilité par les fonctions membres et amies

• protected : visibilités par les fonctions membres et lesstructures dérivées

antislashn.orgC vers C++ 54

Page 55: Passer du langage C au langage C++

Structure

• Exemplestruct identite{

char * nom;void afficher(){

cout << "Nom : " << nom << endl;}

}; pas besoin de préfixer par

antislashn.orgC vers C++ 55

};

int main(){

identite id;id.nom = "Toto";id.afficher();system("PAUSE");

}

pas besoin de préfixer parstruct

structure-identite-1.cpp

Page 56: Passer du langage C au langage C++

Structure

• Déclaration des fonctions membres

– une fonction membre définie à l'intérieur de lastructure est par défaut inline

– une fonction membre peut-être définie à l'extérieurde la structurede la structure

antislashn.orgC vers C++ 56

struct identite{

char * nom;void afficher();

};

void identite::afficher(){

cout << "Nom : " << nom << endl;}

déclaration dans lastructure

définition par le nomcomplètement qualifié de lafonction en utilisantl'opérateur de portée

structure-identite-2.cpp

Page 57: Passer du langage C au langage C++

Structure

• La notion d'encapsulation demande à ce que– les données membres soient privées

• il faut donc des fonctions membres publiques pour les lire et lesmodifier

– les accesseurs / mutateur, ou getter / setter

– les fonctions membres publiques présentent l'interface– les fonctions membres publiques présentent l'interfaced'utilisation de la structure

– l'initialisation de la structure est effectuée à l'aide defonctions adaptées : les constructeurs

• En C++ la structure est peu utilisée car les classessont généralement plus adaptées– par défaut les membres sont privés

antislashn.orgC vers C++ 57

Page 58: Passer du langage C au langage C++

Classe

• Une classe est déclarée par le mot clé class

• La notion de classe ne diffère que sur un seulpoint de celle de structure : les membres sontprivés par défaut– encapsulation des données– encapsulation des données

• Ordre de déclaration des classes– les classes doivent être déclarées avant d'être

employée

– une déclaration incomplète peut-être utilisée• syntaxe : class X;

– forward declaration (déclaration anticipée)

antislashn.orgC vers C++ 58

Page 59: Passer du langage C au langage C++

Classe

• Exempleclass Point{

int x,y;public :

void afficher();void init(int,int);

};x et y sont privées :mise en place d'une fonctiond'initialisation

Point-1.cpp

antislashn.orgC vers C++ 59

void Point::afficher(){

cout << "Point en (" << x << "," << y << ")" << endl;}

void Point::init(int x, int y){

Point::x = x;this->y = y;

}utilisation du pointeur thisthis est l'adresse del'objet qui invoque lafonction

utilisation de l'opérateurde portée

d'initialisation

Page 60: Passer du langage C au langage C++

Classe - .h et .cpp

• Le fichier .h contient

– les propriétés de la classe

– les prototypes des méthodes

• si une méthode est définie dans le .h, elle est considéréecomme inlinecomme inline

• Le fichier .cpp contient les définitions desméthodes

antislashn.orgC vers C++ 60

Page 61: Passer du langage C au langage C++

Classe - .h et .cpp

• Il est fréquent qu'une classe A contienne unattribut de type classe B et que cette mêmeclasse B contienne un attribut de type A– attribut ou argument de fonction

• On se retrouve très vite avec un problème• On se retrouve très vite avec un problèmed'inclusion cyclique

• L'utilisation d'une forward declaration dans le .hpermet de résoudre ce problème– tant que l'on utilise un pointeur ou une référence le

compilateur à juste besoin de connaitre l'existence dela classe

antislashn.orgC vers C++ 61

Page 62: Passer du langage C au langage C++

Classe - .h et .cpp

class B;

class A{B *ptrB;void foo();

};

A.h#include "A.h"#include "B.h"void A::foo(){

A& a = ptrB->getA();}

A.cpp

class A;B.h

#include "A.h"#include "B.h"

B.cpp

Pointeur vers Bpas besoin du .h

antislashn.orgC vers C++ 62

class B{A &refA;

public:B(A &a);A& getA();

};

#include "B.h"

B::B(A &a):refA(a){};

A& B::getA(){return refA;}

#include "A.h"class C{

A a;};

C.h#include "C.h"

C.cpp

Référence vers Apas besoin du .h

Propriété de type Ale compilateur à besoindu constructeur A()inclusion du .h

Page 63: Passer du langage C au langage C++

Classe – conventions de nommage

• Une spécification de développement est un choixconsensuel– établi des règles communes de développement

– améliore la compréhension du code par l'équipe

• Une convention de nommage doit-être mise en• Une convention de nommage doit-être mise enplace– fait partie des spécifications de développement

– doit permettre une auto-documentation du code

– doit avoir un choix approuvé des noms de variables,fonctions, classe, …

antislashn.orgC vers C++ 63

Page 64: Passer du langage C au langage C++

Classe – conventions de nommage

• Les noms donnés à vos classes, méthodes, …forment votre vocabulaire de développement

• Une normalisation est importante

– exemple :

• le nom d'une classe commence par une majuscule

• le nom d'une méthode, variable, propriété par uneminuscule

• utilisation de l'intercapitalisation– camelcase

antislashn.orgC vers C++ 64

Page 65: Passer du langage C au langage C++

Classe – règles de conception

• Encapsulation des propriétés

– par défaut elle sont privées

– mise en place de méthodes d'accès

• exemple de convention : setXxx(…) getXxxx()

• Donner des noms explicites aux méthodes• Donner des noms explicites aux méthodes

• Généraliser le vocabulaire

– utiliser le polymorphisme

• nommer une méthode d'affichage afficher() quelque soitla classe

antislashn.orgC vers C++ 65

Page 66: Passer du langage C au langage C++

Classe – règles de conception

• Exemple issu de Qt – style

– garder à l'esprit que si le code est au moins écrit unefois, il sera lu de nombreuses fois

• il devra être compréhensible et auto-documenté

• ainsi le constructeur suivant est peut intuitif à écrire et à lire• ainsi le constructeur suivant est peut intuitif à écrire et à lire

• il peut être avantageusement remplacé par

antislashn.orgC vers C++ 66

QSlider *slider = new QSlider(12, 18, 3, 13, Qt::Vertical, 0, "volume");

QSlider *slider = new QSlider(Qt::Vertical);slider->setRange(12, 18);slider->setPageStep(3);slider->setValue(13);slider->setObjectName("volume");

Page 67: Passer du langage C au langage C++

Classe – membres de classe

• Les variables de la classe sont appelées– propriétés (attributs en UML)

• Les fonctions de la classe sont appelées– méthodes (opérations en UML)

• Les constructeurs sont des méthodes spécifiques qui sontappelées lors de la construction de la classeappelées lors de la construction de la classe– on parle aussi d'instanciation– sera vu en détail plus tard

• Les destructeurs sont des méthodes spécifiques qui sontappelées avant la désallocation de l'objet– sera vu en détail plus tard

• L'ensemble des méthodes et propriétés forme lesmembres de la classe

antislashn.orgC vers C++ 67

Page 68: Passer du langage C au langage C++

Classe – membres de classe

• Le modificateur const peut être utilisé pour

class Point{int x,y;

public:Point(int i, int j){x=i; y=j;}int getX(){ return x;}int getY(){ return y;}void setX(int x){this->x = x;}void setY(int y){this->y = y;}

};

propriétés privées

constructeur

accesseurs pour lespropriétés privées

• Le modificateur const peut être utilisé pourindiqué qu'une méthode ne modifiera pas lespropriétés de la classe

antislashn.orgC vers C++ 68

class Point {int x,y;

public:Point(int i, int j){x=i; y=j;}int getX()const { return x;}int getY()const { return y;}void setX(int x){this->x = x;}void setY(int y){this->y = y;}

};

les getteurs sont constle compilateur vérifiera lecontrat

Page 69: Passer du langage C au langage C++

Classe – membres de classe

• Une méthode constante ne pourra invoquer quedes méthodes constantesclass Point {

int x,y;public:

Point(int i, int j){x=i; y=j;}int getX() { return x;}

erreur de compilation cargetX() n'est pas const

antislashn.orgC vers C++ 69

int getX() { return x;}int getY() { return y;}void setX(int x){this->x = x;}void setY(int y){this->y = y;}void afficher() const {cout << "x == " << getX() << endl;}

};

getX() n'est pas const

Page 70: Passer du langage C au langage C++

Classe – membres de classe

• Une propriété peut être déclarée mutable pourpouvoir être modifiée par une méthode const

– ATTENTION : le contrat annoncé par la méthode n'estplus respecté

déclaration de x mutable

antislashn.orgC vers C++ 70

class Point {int mutable x;int y;

public:Point(int i, int j){x=i; y=j;}int getX() { return x;}int getY() { return y;}void setX(int x){this->x = x;}void setY(int y){this->y = y;}void verifier() const {if(x==0) x=10;}

};

déclaration de x mutable

méthode const

pas d'erreur de compilationsur l'affectation

Page 71: Passer du langage C au langage C++

Classe – membres de classe

• Les propriétés représentent l'état d'une instance

– en mémoire il y à deux objets de type Point possédant

int main(){Point p1(1,2);Point p2(10,20);

}

– en mémoire il y à deux objets de type Point possédantchacun leur état

antislashn.orgC vers C++ 71

p1:Point

x 1

y 2

p2:Point

x 10

y 20

Page 72: Passer du langage C au langage C++

Classe – membres de classe statique

• Certaines propriétés peuvent être partagées partoutes les instances d'une classe

– propriétés statiques

class Point {static int compteur; propriété partagée par

antislashn.orgC vers C++ 72

static int compteur;int x;int y;

public:Point(int i, int j){x=i; y=j; compteur++;}static int getNbPoints() { return compteur;}

};

int Point::compteur = 0;

int main(){Point p1(1,2);Point p2(10,20);cout << Point::getNbPoints() << endl;

}

propriété partagée partoutes les instances

initialisation de lapropriété statique

méthode statique utilisablesans instancier la classe

invocation de la méthodestatique

Page 73: Passer du langage C au langage C++

Classe – membres de classe statique

• Une méthode statique ne peut utiliser que desmembres statiques

– elle "existe" en dehors de toute instance

p1:Point

antislashn.orgC vers C++ 73

p1:Point

x 1

y 2

p2:Point

x 10

y 20

compteur 2

Page 74: Passer du langage C au langage C++

Classe – membre de classe statique

• Exemple de membre de classe statique de typetableauclass A{private:

static int tabInt[];public:

static int* getTabInt() {return tabInt;}static int getNbElements();

tableau_statique.h

antislashn.orgC vers C++ 74

static int getNbElements();};

int A::tabInt[] = {1,2,3,10,20,30};

int A::getNbElements(){return sizeof(tabInt)/sizeof(tabInt[0]);}

int main(){A a;for(int i=0 ; i<a.getNbElements() ; i++)

cout << a.getTabInt()[i] << endl;}

Page 75: Passer du langage C au langage C++

Classe – pointeur this

• Le pointeur this représente l'instance en cours

• Lors de l'appel des méthodes d'une classe, cepointeur est passé comme premier paramètre

– pointeur "caché"

• la méthode

est converti en

• Le pointeur this n'est pas passé aux méthodesstatiques

antislashn.orgC vers C++ 75

void setY(int y){this->y = y;}

void setY(Point *const this, int y){this->y = y;}

Page 76: Passer du langage C au langage C++

Fonctions et classes amies

• Une fonction qui n'est pas membre d'une classe n'apas accès aux membres privées de cette classe.

• Cette contrainte peut être levée en rendant publiqueles membres privées de la classe auprès de certainesfonctions– mot-clé friend– mot-clé friend

– déclaration des fonctions amies dans la classe– des classes peuvent-être déclarées comme classes amies

• Ceci ne devrait-être qu'une pratique exceptionnelle– des designs patterns permettent de conserver

l'encapsulation• visiteur, commande, …

antislashn.orgC vers C++ 76

Page 77: Passer du langage C au langage C++

Fonctions et classes amies

• Exemple

class Point{

private :int x,y;

public :void init(int,int);

friend void afficher(Point);friend class Ligne;

déclaration de la fonctionamie

déclaration d'une classeamie

Point-2.cpp

antislashn.orgC vers C++ 77

friend class Ligne;};

void afficher(Point p){

cout << "Point en (" << p.x << "," << p.y << ")" << endl;}

class Ligne{public :

void afficher(Point p1, Point p2){

cout << "Ligne depuis (" << p1.x << "," << p1.y << ") et (" << p2.x << "," << p2.y << ")" << endl;}

};

utilisation des membresprivés

Page 78: Passer du langage C au langage C++

Fonctions amies

• Certaines surcharges d'opérateurs peuvent êtreeffectuées via des fonctions amies

– simplification du codage et accès à tous les membres

– la surcharge de l'opérateur d'insertion << permet dedéfinir comment une instance est insérée dans un fluxdéfinir comment une instance est insérée dans un flux

antislashn.orgC vers C++ 78

class Point{int x,y;

public:void init(int,int);friend ostream& operator<<(ostream &o,const Point &p);

};

ostream& operator<<(ostream &o,const Point &p){o << "Point en (" << p.x << "," << p.y << ")" << endl;return o;

}…

Point-3.cpp

Page 79: Passer du langage C au langage C++

Constructeurs et destructeur

• Un constructeur est une fonction membre d'uneclasse– le nom de la fonction est le même que la classe– le constructeur n'a pas de type de retour (pas mêmevoid)

– il peut y avoir plusieurs constructeurs– il peut y avoir plusieurs constructeurs• constructeur par défaut• constructeur de copie• constructeurs de conversion

• Le destructeur est une fonction membre d'une classedont le nom est celui de la classe préfixe par tilde (~)– appelé automatiquement lorsque l'objet est détruit– n'attend pas de paramètre, n'a pas de type de retour

antislashn.orgC vers C++ 79

Page 80: Passer du langage C au langage C++

Constructeurs et destructeurs

• Les objets sont construits dans l'ordred'apparition des déclarations– attention : dans certaines configuration l'ordre d'appel

des constructeurs des variables globales ou statiquesn'est que partiellement défini en C++n'est que partiellement défini en C++

• il peut varier d'un build à l'autre– cf. C++ faq-lite [10.11] [10.12]

– cf. Google Style Guide "Static and Global Variables"

• L'ordre d'appel des destructeurs est inverse del'ordre d'appel des constructeurs

• C++ garantit l'appel du destructeur

antislashn.orgC vers C++ 80

Page 81: Passer du langage C au langage C++

Constructeur par défaut

• Il ne possède pas d'arguments– prototype : nom_classe()

• Il est appelé automatiquement– lors de la définition d'un objet

• <classe> identificateur;<classe> identificateur;

– lors d'une allocation dynamique par new• <classe> * pointeur;

• Si aucun constructeur n'est défini, le compilateur enfournit un par défaut– ATTENTION : dès qu'un constructeur est défini, ce

constructeur par défaut n'est plus fournit• il faut alors le fournir explicitement

antislashn.orgC vers C++ 81

Page 82: Passer du langage C au langage C++

Constructeur par défaut

• Exemple (extrait) class Point{

private :int x,y;

public :void afficher();Point();

};

Point::Point(){

x=10;

prototype du constructeurpar défaut

définition du constructeur

Point-4.cpp

antislashn.orgC vers C++ 82

x=10;y=20;

}…int main(){

Point p;Point * pt = new Point();p.afficher();pt->afficher();

delete pt;}

définition du constructeurpar défaut

objet de type Point allouésur la pile

objet de type Point allouésur le tas (les parenthèsessont facultatives)

libération de la mémoire

Page 83: Passer du langage C au langage C++

Constructeur par défaut

• ATTENTIONTrouvez l'erreur !!!

class Point{

private :int x,y;

public :void afficher();Point();

};

Point::Point(){

x=10;

antislashn.orgC vers C++ 83

x=10;y=20;

}…int main(){

Point p;Point p1();Point * pt = new Point();p.afficher();pt->afficher();delete pt;

}

Page 84: Passer du langage C au langage C++

Constructeur par défaut

• ATTENTIONPoint p1();

– déclare le prototype de lafonction p1

– ne génère pas d'erreur à la

class Point{

private :int x,y;

public :void afficher();Point();

};

Point::Point(){

x=10;– ne génère pas d'erreur à lacompilation

– génère un warning à l'éditionde liens si p1 n'est pas utilisé

• génère une erreur si p1 estutilisé

antislashn.orgC vers C++ 84

x=10;y=20;

}…int main(){

Point p;Point p1();Point * pt = new Point();p.afficher();pt->afficher();delete pt;

}

Page 85: Passer du langage C au langage C++

Destructeur

• Le destructeur est appelé lorsqu'un objet sort desa portée– prototype : ~nom_classe();

• pas de type de retour, pas même void

• pas de paramètres• pas de paramètres

– en général nécessaire s'il y eu allocation de mémoirepar la classe

• notion de composition

– le destructeur peut-êtreinvoqué par l'instance elle-même

• z.~z();

antislashn.orgC vers C++ 85

class Z{int *tab;

public:Z(int taille) {tab = new int[taille];}~Z() { delete [] tab;}

};

Page 86: Passer du langage C au langage C++

Constructeurs de conversion

• Une classe peut comporter plusieursconstructeurs de conversion

– prototype :• nom_classe(liste_de_type);

– il utilise la liste des arguments passés pour construire– il utilise la liste des arguments passés pour construireun nouvel objet

antislashn.orgC vers C++ 86

Page 87: Passer du langage C au langage C++

Constructeurs de conversion

• Exemple (extrait) :class Point{

private :int x,y;

public :void afficher();Point();Point(const Point &);Point(int);Point(int,int);

};Point::Point(int x)

Deux prototypes deconstructeurs de conversion

Définition du premierconstructeur de conversion

Point-6.cpp

antislashn.orgC vers C++ 87

Point::Point(int x){

this->x = x;y = x;

}Point::Point(int x, int y){

this->x = x;this->y = y;

}int main(){

Point p(50,47);Point * pt = new Point(6);

…}

Définition du secondconstructeur de conversion

Création d'une instance surla pile

Création d'une instance surle tas

Page 88: Passer du langage C au langage C++

Constructeurs de conversion

• NotePoint p(3,4);

etPoint p = Point(3,4);

peuvent conduire à un code généré différent, dans lepeuvent conduire à un code généré différent, dans lesecond cas le compilateur peut créer un objettemporaire puis le recopier dans la variable p

• Note

– Point p = 16; appellera le constructeur deconversion Point(int) .

antislashn.orgC vers C++ 88

Page 89: Passer du langage C au langage C++

Constructeurs de conversion

• Note

– Point p = (Point)6.3; provoquera untranstypage et l'appel du constructeur Point(int)

– Point p = (Point)6,4; provoquera un appel dePoint(int) puis l'évaluation de l'expression 4Point(int) puis l'évaluation de l'expression 4

– C++ n'admet qu'un seul niveau de conversion parconstructeur. Soient deux classes A et B ayant commeconstructeurs

• A(int); et B(A);

• une définition telle que B b = 5; est illégale

antislashn.orgC vers C++ 89

Page 90: Passer du langage C au langage C++

Constructeurs de conversion

• Un constructeur à un seul argument définit uneconversion de type qui est appelée implicitementpar le compilateur

Point p = (Point)6.3;

Point p = (Point) 'a';

– des effets de bords peuvent engendrer des ambigüités– des effets de bords peuvent engendrer des ambigüitésqui rendent le programme incompilable

– les conversion implicites peuvent être inhibées enutilisant explicit

• Soyez cohérent et lisible dans l'appel desconstructeurs

antislashn.orgC vers C++ 90

Page 91: Passer du langage C au langage C++

Constructeurs de conversion

• Exemple de conversion ambiguë (extrait)class Z{

public:Z(){};

};

class X{public:

X(Z z){};};

antislashn.orgC vers C++ 91

};

class Y{public:

Y(Z z){};};

void f(X x){ cout << "X" << endl; }void f(Y y){ cout << "Y" << endl; }

int main(){

Z z;f(z);

}

Deux conversions possibles,vers Y ou Xle programme ne compile pas

constructeurs-sans-explicit.cpp

Page 92: Passer du langage C au langage C++

Constructeurs de conversion

• Exemple avec explicit (extrait)class Z{

public:Z(){};

};

class X{public:

X(Z z){};}; la conversion vers la classe

antislashn.orgC vers C++ 92

};

class Y{public:

explicit Y(Z z){};};

void f(X x){ cout << "X" << endl; }void f(Y y){ cout << "Y" << endl; }

int main(){

Z z;f(z);

}

la conversion vers la classeY est inhibée

la conversion est effectuéevers la classe X

constructeurs-avec-explicit.cpp

Page 93: Passer du langage C au langage C++

Constructeur de copie

• Il est appelé implicitement– lors d'une initialisation de la forme :

• T idBis = id; où T est le nom de la classe et id une instance de laclasse T

– peut aussi s'écrire : T idBis(id);

– lors du passage par copie d'un objet en argument d'unefonctionfonction

– lorsqu'une fonction retourne un objet par valeur– lorsqu'un pointeur sur un objet reçoit une valeur par

l'opérateur new• T *pt = new T(t); où t est une instance de T

• S'il n'existe pas de constructeur de copie, C++ en fournit unpermettant une copie superficielle de l'objet– copie bit à bit de l'objet, attention donc aux membres de type

pointeur

antislashn.orgC vers C++ 93

Page 94: Passer du langage C au langage C++

Constructeur de copie

• Deux prototypes possibles• nom_classe (nom_classe &);

• nom_classe (const nom_classe &);

– préférable car passage d'un argument const ou non

• ATTENTION– il faut distinguer une création par copie– il faut distinguer une création par copie

• T new_t = t;

– d'une affectation• old_t = t; où old_t et t sont des objets déjà existants

– il est alors fait appel à l'opérateur d'affectation (=)• par défaut, effectue une copie de surface, il faut donc

souvent le redéfinir si certains membres sont des pointeurs

antislashn.orgC vers C++ 94

Page 95: Passer du langage C au langage C++

Constructeur de copie

• Exemple (extrait) :class Point{

private :int x,y;

public :void afficher();Point();Point(const Point &);

prototype constructeur decopie

Point-5.cpp

antislashn.orgC vers C++ 95

Point(const Point &);

};…Point::Point(const Point &p){

x = p.x;y = p.y;

}…int main(){

Point p;Point p1 = p;…

}

définition du constructeurde copie

Création d'une instance dePoint par appel duconstructeur de copie surl'instance p

Page 96: Passer du langage C au langage C++

Tableau d'objets

• La syntaxe du C est utilisable pour initialiser destableaux d'instances de classe

– la classe doit posséder les constructeurs adéquats

class Point{Point-7.cpp

antislashn.orgC vers C++ 96

class Point{int x, y;public:

Point(){x=y=0;}Point(int a) {x=y=a;}Point(int x, int y){this->x = x; this->y = y;}void afficher(){ cout << "Point en (" << x << "," << y << ")\n";}

};

int main(){Point tp[] = {2,Point(),Point(3),Point(4,5)};for(int i=0 ; i < sizeof(tp)/sizeof(tp[0]) ; i++)

tp[i].afficher();system("PAUSE");

}

Page 97: Passer du langage C au langage C++

Tableau d'objets

• Lors de l'allocation mémoire par new[] leconstructeur par défaut est appelé

– le delete[] invoquera le destructeur

…tableau_objets.cpp

antislashn.orgC vers C++ 97

…int main(){

int NB = 5;

Point *tp2 = new Point[NB];

delete [] tp2;}…

Page 98: Passer du langage C au langage C++

Liste d'initialisation

• C++ apporte un nouveau mécanismed'initialisation des membres d'une classe par unconstruteur

– la liste d'initialisation

– syntaxe :– syntaxe :nom_classe(liste_parametres) : liste_initialisateurs {corps}

– l'ordre d'initialisation est celui dans lequel lesmembres apparaissent dans la classe et non pasl'ordre dans la liste

antislashn.orgC vers C++ 98

Page 99: Passer du langage C au langage C++

Liste d'initialisation

• Exemple (extrait)class A{

int i;double d;char c;

public :A(int k) : i(k), d(18.06), c('a') {};

};

liste-initialisation-1.cpp

– l'appel du constructeur A a(20); initialisera lesmembres à

• i == 20

• d == 18.06

• c == 'a'

antislashn.orgC vers C++ 99

Page 100: Passer du langage C au langage C++

Liste d'initialisation

• La liste d'initialisation est utilisée pourl'initialisation d'une instance de classe qui elle-même comporte un objet d'une autre classe.

• Dans l'exemple suivant :

antislashn.orgC vers C++ 100

class A{int i;

public :A() {i=0;}A(int k) {i=k;}

};

class B{int i;A a;

public :B() {i=0;}

};

Page 101: Passer du langage C au langage C++

Liste d'initialisation

• Lors d'une déclaration B b; le compilateur va :

– allouer l'espace pour b

– initialiser le membre a en appelant le constructeur pardéfaut A()

– initialiser le reste de b en appelant le constructeur par– initialiser le reste de b en appelant le constructeur pardéfaut B()

• Comment fixer une valeur à l'instance a ?• sans que le compilateur appelle plusieurs fois le

constructeur A()

– utiliser une liste d'initialisation

antislashn.orgC vers C++ 101

Page 102: Passer du langage C au langage C++

Liste d'initialisation

• Exemple (extrait)

– en rencontrant a(20) le compilateur va initialiser a.ien invoquant le constructeur A(20)

class A{int i;

public :

• La liste d'initialisation permet d'optimiser le code

antislashn.orgC vers C++ 102

public :A() {i=0;}A(int k) {i=k;}

};

class B{int i;A a;

public :B() : a(20) {i=0;}

};

Page 103: Passer du langage C au langage C++

Liste d'initialisation

• Initialisation d'une propriété constant ouréférence

– seule la liste d'initialisation permet d'initialiser cespropriétés

antislashn.orgC vers C++ 103

int j = 3;class A{

const int x;int &y;

public :A() : x(7), y(j) {}A(int k) {x = k;}

};

Illégal car x est constantet y est une référence

A(int k):x(k),y(j) {}

OK, liste d'intialisation

Page 104: Passer du langage C au langage C++

C++11 – Délégation de constructeur

• En C++ un constructeur ne peut pas appeler unautre constructeur de cette même classe

– duplication potentielle de code

– utilisation d'une méthode privée pour factoriser lecodecode

• C++11 permet à un constructeur de déléguer lecréation d'une instance à un autre constructeur

antislashn.orgC vers C++ 104

Page 105: Passer du langage C au langage C++

C++11 – Délégation de constructeur

• Exemple de code

class Point{int x;int y;

antislashn.orgC vers C++ 105

public :Point(int x, int y):x(x),y(y){}Point(int xy):Point(xy,xy){}

};

Page 106: Passer du langage C au langage C++

Opérateur de conversion

• Un constructeur peut être appelé pour effectuerune conversion de type

• exemple : Point p = (Point)6.3;

– ceci ne permet que les conversions dont le type cibleest la classe elle-mêmeest la classe elle-même

– il est possible de définir un opérateur de conversiondans une classe

• syntaxe : operator type () {…}– le type retourné dans le code doit correspondre au type redéfini

– pas d'indication du type retourné

• il sera implicitement appelé chaque fois qu'une conversionsera nécessaire

antislashn.orgC vers C++ 106

Page 107: Passer du langage C au langage C++

Opérateur de conversion

• Exempleclass Point{

int x,y;public:

Point(int x, int y) {this->x = x; this->y = y; }

operator int() {return x+y;}};

définition de la conversion

Point-8.cpp

antislashn.orgC vers C++ 107

int main(){

Point p = Point(2,3);cout << p*2 << endl;system("PAUSE");

}

vers int

invocation de la conversionvers int

Page 108: Passer du langage C au langage C++

Objets constants

• Si un objet est déclaré constant, les fonctionsmembres ne sont plus utilisables

– les fonctions membres doivent être déclarées const

• fait partie de la signature

antislashn.orgC vers C++ 108

class X{

int i;public :

X(int i) {this->i = i;}int doubler() const {return i*2;}

};

int main(){

const X x(3);cout << x.doubler() << endl;system("PAUSE");

}

objet-constant.cpp

Page 109: Passer du langage C au langage C++

Propriété constante

• Une propriété peut-être déclarée const

– comment l'initialiser ?

• Membre de classe non statique et constant

– initialisation par une liste d'initialisationinitialisation par une liste d'initialisation

antislashn.orgC vers C++ 109

class X{

const int i;public :

X(int j) : i(j) {}int doubler() const {return i*2;}

};

liste d'initialisation

Page 110: Passer du langage C au langage C++

Propriété constante

• Membre de classe statique et constant

– initialisation au moment du chargement duprogramme

class X{

objet-constant.cpp

antislashn.orgC vers C++ 110

{static const int i;

public :X() {}int doubler() const {return i*2;}

};const int X::i = 3;int main(){

const X x;cout << x.doubler() << endl;system("PAUSE");

}

initialisation au chargementdu programme

Page 111: Passer du langage C au langage C++

Surcharge des opérateurs

• C++ permet de surcharger les opérateurs– par exemple utiliser l'opérateur + pour "additionner" deux

instances de la classe Point

– il est impossible de redéfinir les opérations prédéfinies en C++

– on ne peut pas créer de nouveaux opérateurs

– les opérateurs suivants ne peuvent pas être surchargés– les opérateurs suivants ne peuvent pas être surchargés. :: ?: sizeof .*

– les règles de précédences et d'associativités sont conservées

– la syntaxe de la surcharge de certains opérateurs est soumise àdes règles spécifiques

• affectation = appel de fonction () indexation [] accès ->

• ++ et -- doivent tenir compte des formes préfixées et suffixées

antislashn.orgC vers C++ 111

Page 112: Passer du langage C au langage C++

Surcharge des opérateurs

• Syntaxe générale pour la surcharge d'unopérateur :

– type operator op(types des opérandes);

• ou op est l'opérateur à surcharger

• Surcharge au niveau global• Surcharge au niveau global

– définition en dehors de la classe

– l'appel est équivalent à operator+(p1,p2);

antislashn.orgC vers C++ 112

Point operator+(Point &p1, Point &p2){

int x = p1.getX() + p2.getX();int y = p1.getY() + p2.getY();return Point(x,y);

}

Page 113: Passer du langage C au langage C++

Surcharge des opérateurs

• De manière générale, si un opérateur est défini auniveau de la classe il attend un paramètre demoins que le nombre d'opérandes

– exemplePoint-9.cpp

antislashn.orgC vers C++ 113

class Point{int x,y;

public:Point(int x, int y) {this->x = x; this->y = y; }void afficher(){ cout << "Point en (" << x << "," << y << ")\n";}Point operator +(Point &p){ return Point(x + p.x,y + p.y); }Point operator-(){ return Point(-x, -y);}

};int main(){

Point p1(2,3);Point p3 = -p1;p3.afficher();

}

opérateur binaire +

opérateur unaire -

Point-9.cpp

Page 114: Passer du langage C au langage C++

Surcharge des opérateurs

• Surcharge au niveau de la classe

– définition dans la classe

– l'objet de classe qui invoque est le membre de gauche

– l'appel est équivalent à p1.operator+(p2);

antislashn.orgC vers C++ 114

class Point{int x,y;

public:Point(int x, int y) {this->x = x; this->y = y; }void afficher(){ cout << "Point en (" << x << "," << y << ")\n";}Point operator +(Point &p){

return Point(x + p.x,y + p.y);}

};

Page 115: Passer du langage C au langage C++

Surcharge des opérateurs

• Surcharge des opérateurs ++ et --

– la définition des opérateurs préfixés est standard

– la définition des opérateurs suffixés s'effectue enajoutant un int comme paramètre supplémentaire àla signaturela signature

antislashn.orgC vers C++ 115

class Point{int x,y;

public:Point(int x, int y) {this->x = x; this->y = y; }void afficher(){ cout << "Point en (" << x << "," << y << ")\n";}Point &operator++() { ++x;++y; return *this;}Point &operator++(int) { x++;y++; return *this;}

};

Point-9.cpp

ATTENTION : code nonfonctionnel

Page 116: Passer du langage C au langage C++

Surcharge des opérateurs

• Surcharge de l'opérateur d'affectation =

– par défaut fait une copie de surface de la classeclass Tableau{

int *tab; int taille;public:…

Tableau &operator=(const Tableau &t){if(this != &t)

{

t correspondra à t1

antislashn.orgC vers C++ 116

{delete [] tab;taille = t.taille; tab = new int[taille];for(int i=0 ; i<taille ; i++) tab[i] = t.tab[i];

}return *this;

} …};int main(){

Tableau t1(5);Tableau t2;for(int i=0 ; i<5 ; i++) t1.set(i,i);t2 = t1;

…}

appel de operator=Attention :Tableau t2 = t1; aurait appelé leconstructeur de copie

t2 est l'objet sur qui estinvoqué operator=()

operateur-affectation.cpp

Page 117: Passer du langage C au langage C++

Surcharge des opérateurs

• Surcharge de l'opérateur d'indexation []

– ne peut qu'être qu'un membre de classe

– considéré comme un opérateur binaire

• x[y] est interprété comme x.operator[](y)

– dans une expression telle que– dans une expression telle que• x[i] = y[i] + 1;

• il faut que l'affectation se fasse sur x[i], il faut donc queoperator[] renvoie une lvalue, ce qui est fait en renvoyantune référence

– sinon erreur à la compilation (pas une lvalue)

antislashn.orgC vers C++ 117

Page 118: Passer du langage C au langage C++

Surcharge des opérateurs

• Exemple de surcharge de l'opérateur [] (extrait)

class Tableau{int *tab;int taille;

public:...

int &operator[](int i){return tab[i];}

antislashn.orgC vers C++ 118

{return tab[i];}...};

int main(){

Tableau t1(5);Tableau t2;Tableau t3(1);

...t3[0] = t1[1] + t2[3];

...}

renvoie une référence verstab[i]

affectation possible car uneréférence est renvoyée

operateur-crochets.cpp

Page 119: Passer du langage C au langage C++

Surcharge des opérateurs

• Surcharge de l'opérateur d'appel de fonction ()

– nommé aussi foncteur ou objet fonction

– uniquement en tant que fonction d'une classe

– opération binaire

est interprété comme• c(x,y) est interprété comme c.operator()(x,y)

• prototype de la formetype operator() (paramètres);

– ne pas confondre avec l'opérateur de conversion

• rappel plus loin

antislashn.orgC vers C++ 119

Page 120: Passer du langage C au langage C++

Surcharge des opérateurs

• Exemple de foncteurs

class Inferieur{public:

bool operator()(int i, int j) { return i < j; }bool operator()(char a, char b) { return a < b; }bool operator()(char *s1, char *s2) {return strcmp(s1,s2) < 0; }

};

antislashn.orgC vers C++ 120

int main(){

Inferieur inf;cout << inf(1,2) << endl;cout << inf('z','a') << endl;cout << inf("aa","bb") << endl;system("PAUSE");

}foncteur.cpp

Page 121: Passer du langage C au langage C++

Surcharge des opérateurs

• Opérateur de conversion – rappel• syntaxe : operator type () {…}

– le type retourné doit correspondre au type redéfini

• il sera implicitement appelé chaque fois qu'une conversionsera nécessaire

antislashn.orgC vers C++ 121

class Point{int x,y;

public:Point(int x, int y) {this->x = x; this->y = y; }

operator int() {return x+y;}};

int main(){

Point p = Point(2,3);cout << p*2 << endl;system("PAUSE");

}

définition de la conversionvers int

invocation de la conversionvers int

Page 122: Passer du langage C au langage C++

Surcharge des opérateurs

• Les surcharges utilisables et leurs syntaxes sontrésumés sur le site Wikipedia– http://en.wikipedia.org/wiki/Operators_in_C_and_C++

antislashn.orgC vers C++ 122

Page 123: Passer du langage C au langage C++

C++11 – Rvalue Reference

• Une lvalue est une expression possédant un nomet qui reste en mémoire un certain temps– une variable est une lvalue

• Une rvalue n'a pas de nom et ne persiste pas– un entier littéral n'a pas de nom et sa portée est très– un entier littéral n'a pas de nom et sa portée est très

courte

– valeur retour de fonction

• Les rvalue references prennent en charge lasémantique de déplacement– syntaxe : &&

antislashn.orgC vers C++ 123

Page 124: Passer du langage C au langage C++

C++11 – Rvalue Reference

• Introduction d'une sémantique de déplacement(move)– en C++ il n'y a pas de manière générique de déplacer

un objet• si une fonction retourne un objet de taille importante, celui-

ci est copié dans une zone temporaire avant d'être à• si une fonction retourne un objet de taille importante, celui-

ci est copié dans une zone temporaire avant d'être ànouveau copié vers la zone où le résultat de la focntion estaffecté

– C++11 ajoute les Rvalues Reference• permet d'appeler la fonction "MoveFrom" à la place du

constructeur de copie si la copie correspond à undéplacement

antislashn.orgC vers C++ 124

Page 125: Passer du langage C au langage C++

C++11 – Constructeur de déplacement

• Extrait de codeclass MyContainer{

int nSize;char* pString;

public:MyContainer(MyContainer&& s){

moveIt(*this, s);}

antislashn.orgC vers C++ 125

}protected:

static void moveIt(MyContainer& tgt, MyContainer& src){cout << "Moving " << src.pString << endl;tgt.nSize = src.nSize;tgt.pString = src.pString;src.nSize = 0;src.pString = nullptr;

}...}

Page 126: Passer du langage C au langage C++

C++11 – Opérateur de déplacement

• Extrait de codeclass MyContainer{

int nSize;char* pString;

public:MyContainer& operator=(MyContainer&& s){

delete pString;moveIt(*this, s);return *this;

antislashn.orgC vers C++ 126

return *this;}

protected:static void moveIt(MyContainer& tgt, MyContainer& src){

cout << "Moving " << src.pString << endl;tgt.nSize = src.nSize;tgt.pString = src.pString;src.nSize = 0;src.pString = nullptr;

}...}

Page 127: Passer du langage C au langage C++

C++11 - Sémantique de déplacement

• Par rapport aux constructeur et opérateur decopie – extrait de code...public:

MyContainer(const MyContainer& s){copyIt(*this, s);

}MyContainer& operator=(MyContainer& s){

antislashn.orgC vers C++ 127

MyContainer& operator=(MyContainer& s){delete pString;copyIt(*this, s);return *this;

}protected:

static void copyIt(MyContainer& tgt,const MyContainer& src){cout << "Copying " << src.pString << endl;delete tgt.pString;tgt.nSize = src.nSize;tgt.pString = new char[tgt.nSize];strncpy(tgt.pString, src.pString, tgt.nSize);

}...

Page 128: Passer du langage C au langage C++

C++11 - Sémantique de déplacement

• Fonction utilitaires de la bibliothèque utility

– std::move()

• retourne une référence à une rvalue– fonction de transtypage

• prend pour paramètre une référence à une lvalue ou une• prend pour paramètre une référence à une lvalue ou unervalue

– std::forward()

• fait suivre une variable– retourne une lvalue reference si la variable est une lvalue reference

– retourne une rvalue reference si la variable est une rvaluereference

antislashn.orgC vers C++ 128

Page 129: Passer du langage C au langage C++

Les patrons

• Si plusieurs fonctions sont définies de la mêmefaçon et ne diffèrent que par les typesd'arguments, le développeur doit créerl'ensemble des fonctions

– en C on peut définir une macro préprocesseur

– le C++ fournit un mécanisme de patrons (templates)de fonction

• cette méthode s'étend aux classes

antislashn.orgC vers C++ 129

int max(int a, int b) { return (a>b) ? a : b ; }double max(double a, double b) { return (a>b) ? a : b ; }

#define MAX(a,b) ((a)>(b)) ? a : b

Page 130: Passer du langage C au langage C++

Patron de fonction

• Les types des arguments ne sont pas fixés et sontconsidérés eux-mêmes comme des paramètres– syntaxe

• template<typename parametre[,…]> définition_fonction

– la fonction max devient– la fonction max devient

– le compilateur va générer le code des fonctions entenant compte des appels

• si une fonction du même nom avec les bons types deparamètre existe déjà, le compilateur l'utilisera

– class peut être utilisé au lieu de typename

antislashn.orgC vers C++ 130

template <typename T> T max(T &a,T &b) { return (a>b) ? a : b ; }

Page 131: Passer du langage C au langage C++

Patron de classe

• Il peut arriver que plusieurs classes soientdéfinies de manières identiques, aux types près

– un patron de classe peut alors être utilisé

– syntaxe :• template <typename parametre[,…]> class nom_class{…}• template <typename parametre[,…]> class nom_class{…}

antislashn.orgC vers C++ 131

template <typename T> class Tableau{T tab[2];

public:Tableau(T x,T y) {tab[0]=x;tab[1]=y;}void afficher(){ cout << tab[0] << "\t" << tab[1] << endl;}

};int main(){

Tableau<int> t1(1,2);Tableau<char> t2('a','z');t1.afficher();t2.afficher();

}

génération des classes enprécisant le type

template-classe.cpp

Page 132: Passer du langage C au langage C++

Patron de classe

• Le compilateur générera les classes nécessaires

• Un patron de classe est entièrement codé dans lefichier .h– on ne peut pas pré-compiler un template

– pas de fichier .cpp– pas de fichier .cpp

• Si les déclarations et définitions sont séparées lenom de la méthode doit être complètementqualifié– dans le même fichier .h (pas de .cpp)

– les méthodes ne sont pas inline

antislashn.orgC vers C++ 132

Page 133: Passer du langage C au langage C++

Patron de classe

• Déclarations et définitions séparées

template <typename T> class Tableau{T tab[2];

public:Tableau(T x,T y) {tab[0]=x;tab[1]=y;}void afficher();

};

antislashn.orgC vers C++ 133

};

template<typename T> void Tableau<T>::afficher(){ cout << tab[0] << "\t" << tab[1] << endl;}

Page 134: Passer du langage C au langage C++

Patron de classe

• Il est possible de préciser un paramètre templatepar défaut

template <typename T, typename Y=int> class Toto{T t;Y y;

};

type par défaut

antislashn.orgC vers C++ 134

};

int main(){Toto<int> t1;Toto<double,double> t2;

}

équivalent à Toto<int,int>

Page 135: Passer du langage C au langage C++

typename

• typename est utilisé pour introduire un typegénérique– class peut aussi être utilisé

• typename sert aussi à introduire les identificateursde types inconnus dans les templatesde types inconnus dans les templates

antislashn.orgC vers C++ 135

class A{public:

typedef int Y;};

template <class T> class X{

typename T::Y i;};

int main(){X<A> x;

};

type définit dans la classe A

la classe X suppose que letype générique T définit untype Y

typename.cpp

Page 136: Passer du langage C au langage C++

Membres statiques

• Donnée statique– la classe contient la déclaration de la donnée statique

– la définition de la donnée statique s'effectue au niveau global

class Point{int x,y;

public:déclaration

membres-static.cpp

antislashn.orgC vers C++ 136

public:static int nombre;Point(int x, int y) { this->x = x ; this->y = y; nombre++;}Point(){x=y=0; nombre++;}~Point() {nombre--;}void afficher(){cout << "Point " << nombre << " en (" << x << "," << y << ")\n";}

};int Point::nombre=0;int main(){

Point p1;Point p2(5,6);p1.afficher();p2.afficher();system("PAUSE");

}

définition et initialisation

Page 137: Passer du langage C au langage C++

Membres statiques

• Fonction statique

– n'a pas accès aux membres non statiques

– le pointeur this n'est pas passé à la fonction statiqueclass Point{

int x,y;static int nombre;

déclaration (privée)

antislashn.orgC vers C++ 137

static int nombre;public:

Point(int x, int y) { this->x = x ; this->y = y; nombre++;}Point(){x=y=0; nombre++;}~Point() {nombre--;}static int getNombre() {return nombre;}void afficher(){ cout << "Point " << nombre << " en (" << x << "," << y << ")\n";}

};int Point::nombre=0;int main(){

Point p1;Point p2(5,6);

cout << Point::getNombre() << endl;system("PAUSE");

}

fonction d'accès statique

appel de la fonction statique

membres-static.cpp

Page 138: Passer du langage C au langage C++

Héritage

• Syntaxe de baseclass classe_derivee : type_protection classe_base {…};

– le type de protection définit l'accessibilité dans laclasse dérivée des membres de la classe de base

• on ne peut que restreindre l'accessibilité• on ne peut que restreindre l'accessibilité

• dans tous les cas les membres privés de la classe de base nesont pas accessibles dans la classe dérivée

– public : on conserve les accessibilités

– protected : les membres publiques et protégés de la classe debase deviennent protégés dans la classe dérivée

– private : les membres publiques et protégés de la classe de basedeviennent privés dans la classe dérivée

antislashn.orgC vers C++ 138

Page 139: Passer du langage C au langage C++

Héritage

• La classe dérivée hérite de l'ensemble desmembres de la classe de base

– les membres privés sont hérités mais ne sont pasaccessible par la classe dérivée

• principe d'encapsulation, il faut fournir des méthodes• principe d'encapsulation, il faut fournir des méthodespubliques pour accéder aux propriétés privées

– il y réunion des membres

• chaque objet de la classe dérivée contient un objet de laclasse de base

antislashn.orgC vers C++ 139

Page 140: Passer du langage C au langage C++

Héritage

• Empreinte mémoire

– la classe B dérive de la classe Aclass A{

char ta[256];};

class B : public A{

heritage-1.cpp

antislashn.orgC vers C++ (version v1.1) 140

class B : public A{char tb[256];

};

int main(){

cout << "Encombrement de A : " << sizeof(A) << endl;cout << "Encombrement de B : " << sizeof(B) << endl;

}

char ta[256] char ta[256]

char tb[256]instance de A

instance de B

sous instance A

Page 141: Passer du langage C au langage C++

Héritage

• Exemple

class Vehicule{char *marque;

public:Vehicule(){marque = "INCONNU"; }Vehicule(char * marque){this->marque = marque;}void afficher() {cout << "Vehicule - marque : "<<marque<<endl;}

};

Vehicule-1.cpp

antislashn.orgC vers C++ 141

};

class Voiture : public Vehicule{};

int main(){

Voiture v1;v1.afficher();system("PAUSE");

}

Voiture spécialise Véhicule

utilisation de la méthode dela classe de base

Page 142: Passer du langage C au langage C++

Héritage – sous-typage

• Conversion de classe dérivée en classe de base

– la conversion est implicite dès que cela est nécessaire

– la visibilité est alors réduite à la classe de base

class Voiture : public Vehicule{public:

Vehicule-1.cpp

antislashn.orgC vers C++ 142

public:void rouler(){cout << "La voiture " << getMarque() << " roule\n";}

};

int main(){

Voiture v1;v1.afficher();v1.rouler();Vehicule v2 = v1;v2.rouler();system("PAUSE");

}

accesseur défini dansVehicule pour la propriétéprivée de Vehicule

OK : v1 est de type Voiture

ERREUR : v2 est de typeVehicule

Page 143: Passer du langage C au langage C++

Héritage – forçage vers la classe dérivée

• Il est illicite de convertir un type de base vers untype dérivé.

• Un pointeur sur la classe de base peut êtreconverti en un pointeur vers la classe dérivée

– conversion explicite

– n'a de sens que si l'objet concret pointé par lepointeur est bien du type de la classe dérivée

antislashn.orgC vers C++ 143

Page 144: Passer du langage C au langage C++

Héritage – forçage vers la classe dérivée

• Exempleclass Vehicule{

char *marque;public:

Vehicule(){marque = "INCONNU"; }Vehicule(char * marque){this->marque = marque;}void afficher() {cout << "Vehicule - marque : "<<marque<<endl;}char * getMarque(){ return marque;}

};

Vehicule-1.cpp

antislashn.orgC vers C++ 144

class Voiture : public Vehicule{public:

void rouler(){cout << "La voiture " << getMarque() << " roule\n";}};

int main(){

Voiture *vo1 = new Voiture();Vehicule *ve1 = vo1;Voiture *vo2;vo2 = (Voiture *) ve1;vo2->rouler();system("PAUSE");

}

OK car ve1 pointe vers unobjet concret Voiture

sous-typageve1 de type Vehicule pointevers un objet concret detype Voiture

Page 145: Passer du langage C au langage C++

Héritage

• L'accès à un membre peut être désignés par son nom ou par son nomcomplètement qualifié.– si le nom du membre de classe à la même nom dans la classe de base et la

classe dérivée, la référence au membre de la classe de base passe par lenom qualifié

class A{public:

heritage-2.cpp

antislashn.orgC vers C++ 145

public:void f() { cout << "A::f()\n";}

};

class B : public A{public:

void f() { cout << "B::f()\n";}};

int main(){

A a; B b;a.f(); b.f();b.A::f();system("PAUSE");

}

accès à la fonction de laclasse de base

Page 146: Passer du langage C au langage C++

Héritage – les constructeurs

• Chaque fois qu'un constructeur d'une classedérivée est appelé, le constructeur de la classe debase est d'abord appelé

– deux cas sont à considérés

• le cas général• le cas général

• le cas du constructeur de copie

antislashn.orgC vers C++ 146

Page 147: Passer du langage C au langage C++

Héritage – les constructeurs

• Cas général

– si un constructeur de la classe dérivée est appelé(autre que le constructeur de copie)

• le constructeur de la classe de base appelé est celui qui estprésent dans la liste d'initialisationprésent dans la liste d'initialisation

• s'il n'y a pas de liste d'initialisation, le constructeur pardéfaut de la classe de base est appelé

• si aucun constructeur n'est défini dans la classe dérivée, leconstructeur par défaut de la classe de base est appelé

antislashn.orgC vers C++ 147

Page 148: Passer du langage C au langage C++

Héritage – les constructeurs

• Exemple : cas généralclass A{public:

A(){ cout << "A()\n";}A(int i){ cout << "A(int i)\n";}

};

class B : public A{public:

heritage-3.cpp

antislashn.orgC vers C++ 148

public:B(){ cout << "B()\n";}B(int i):A(i){ cout << "B(int i)\n";}B(char c){ cout << "B(char c)\n";}

};

int main(){

B b;cout << endl;B c(1);cout << endl;B d('a');cout << endl;system("PAUSE");

}

Page 149: Passer du langage C au langage C++

Héritage – les constructeurs

• Cas du constructeur de copie– lorsqu'une classe ne possède pas de constructeur par

copie le compilateur en fournit un

– si la classe dérivée n'a pas de constructeur de copie, leconstructeur de copie (défini ou par défaut) de laconstructeur de copie (défini ou par défaut) de laclasse mère est appelé

– si la classe fille possède un constructeur de copie, leconstructeur de la classe mère appelé dépend de laliste d'initialisation

• si la liste est absente ou n'indique pas de constructeur pourla classe mère, c'est le constructeur par défaut de la classemère qui est appelé

antislashn.orgC vers C++ 149

Page 150: Passer du langage C au langage C++

Héritage – les constructeurs

• Exemple : constructeur de copie

class A{public:

A(){ cout << "A()\n";}A(const A &a){ cout << "A(const A &a)\n";}

};class B : public A{public:

B(){ cout << "B()\n";}

appel du constructeur pardéfaut de A

heritage-4.cpp

antislashn.orgC vers C++ 150

B(){ cout << "B()\n";}B(const B &b){ cout << "B(const B &b)\n";}

};class C : public A{public:

C(){ cout << "C()\n";}C(const C &c):A(c){ cout << "C(const C &c)\n";}

};int main(){

B b1;B b2 = b1;C c1;C c2 = c1;

}

appel du constructeur decopie de A

Page 151: Passer du langage C au langage C++

Héritage - template

• Un template peut hériter d'un autre template

• Une classe peut hériter d'un template

template <typename T> class X{T t;

};

heritage_template.cpp

antislashn.orgC vers C++ 151

};

template <typename U, typename V> class Y : public X<U>{V u;

};

class V : public X<float>{};

int main(){Y<int,double> y;V v;

}

Page 152: Passer du langage C au langage C++

Dérivation et opérateur d'affectation

• Similaire au constructeur de copie

– soit b2 = b1; où b1 et b2 sont des instancesd'une classe B dérivée de A

– si l'opérateur d'affectation de B n'a pas été redéfini,l'opérateur d'affectation de A est appelél'opérateur d'affectation de A est appelé

– si l'opérateur d'affectation de B a été redéfini,l'opérateur d'affectation de A n'est pas appelé

• toutes les affectations de la partie de la classe B dépendantde A doivent être codée explicitement

antislashn.orgC vers C++ 152

Page 153: Passer du langage C au langage C++

Dérivation et opérateur d'affectationclass A{public:

A(){cout << "++ CONSTRUCTEUR A()" << endl;}A(const A &a){cout << "++ CONSTRUCTEUR COPIE A(const A &a)" << endl;}A &operator=(const A &a) {

cout << "=> OPERATOR=(const A &a) de A" << endl;return *this;}

};

class B : public A{public:

B(){cout << "++ CONSTRUCTEUR B()" << endl;}B(const B &b){cout << "++ CONSTRUCTEUR COPIE B(const B &b)" << endl;}

heritage-5.cpp

antislashn.orgC vers C++ 153

B &operator=(const B &b) {A *pa1 = this;A *pa2 = const_cast<B*> (&b);*pa1 = *pa2;cout << "=> OPERATOR=(const B &b) de B" << endl;return *this;}

};

int main(){

B b1;cout << "============================" << endl;B b2;cout << "============================" << endl;b1 = b2;cout << "============================" << endl;

}

affectation de la partie Ade l'instance

Page 154: Passer du langage C au langage C++

Polymorphisme

• Un des principes du polymorphisme est qu'une classe dérivéeest compatible avec sa classe de base.– là où une Figure est prévue on doit pouvoir y substituer un Carre

• tous les services offerts par une Figure sont offert par un Carre– sous réserve des droits d'accès

• la conversion d'une classe vers sont type de base est une conversionstandard

Carre c;Figure f = c;

antislashn.orgC vers C++ 154

class Figure{public:

void afficher(){cout << "A CODER" << endl;

}};

class Carre : public Figure{public:

void afficher(){cout << "AFFICHAGE D'UN CARRE" << endl;

}};

Figure-1.cpp

Page 155: Passer du langage C au langage C++

Polymorphisme

• Selon que l'on applique cette conversion sur des objets oudes pointeurs la conversion est effectuée différemment

• Convertir un objet Carre vers un objet Figure revient à luienlever les membres qui ne font pas partie de Carre– il y a perte effective d'information

– peut être vu comme l'appel implicite d'une méthode de– peut être vu comme l'appel implicite d'une méthode deconversion de Carre vers Figure

antislashn.orgC vers C++ 155

Carre c;Figure f = c;

Figure

Carre

Figure

instance c

static_cast<Figure> (c)

Page 156: Passer du langage C au langage C++

Polymorphisme

• Convertir un pointeur vers Carre vers un pointeurvers Figure ne fait perdre aucune information

– l'instance n'offre que les services de Figure, mais il necesse pas d'être un Carre avec tous ces membres

antislashn.orgC vers C++ 156

Carre c;Figure *pf = &c; Figure

Carre

pf static_cast<Figure *> (&c)

Page 157: Passer du langage C au langage C++

Polymorphisme

• Exemple

– seul l'appel de l'affichage d'un Carre par un objet detype Carre fonctionne !!!

– il faut distinguer le type statique et le type dynamique

antislashn.orgC vers C++ 157

int main(){

Carre c;Figure f1;Figure f2 = c;Figure *f3 = &c;Figure &rf = c;c.afficher();f1.afficher();f2.afficher();f3->afficher();rf.afficher();

}

Figure-1.cpp

Page 158: Passer du langage C au langage C++

Polymorphisme

• Par défaut la détermination du membre accédé à travers unpointeur ou une référence est fait durant la compilation– donc par le type statique du pointeur ou de la référence– le type statique d'une expression est connu à la compilation– le type dynamique est déterminé par la valeur courante de

l'expression• peut évoluer durant l'exécution• peut évoluer durant l'exécution

• Par défaut la détermination du membre à accéder à travers unpointeur ou une référence se fait durant la compilation– c'est-à-dire d'après le type statique du pointeur ou de la référence

• Pour que la détermination soit effectuée dynamiquement il fautdéclarer les fonctions virtuelles– quand déclarer une fonction virtuelle ?

• si une fonction est redéfinie dans les classes dérivées• si une fonction est appelée à travers des pointeurs ou références

antislashn.orgC vers C++ 158

Page 159: Passer du langage C au langage C++

Fonctions virtuelles

• Types statiques et dynamiquesclass B {};class D : public B {};

int main(){

D d;B b = d;B *pb = &d;

– le type statique de *pb et de rb est B

• analyse du programme, déterminé à la compilation

– le type dynamique de *pb et de rb est D

antislashn.orgC vers C++ 159

B *pb = &d;B &rb = d;

}

Page 160: Passer du langage C au langage C++

Fonctions virtuelles

class Figure{public:

virtual void afficher(){cout << "A CODER" << endl;

}};

class Carre : public Figure{public:

void afficher(){cout << "AFFICHAGE D'UN CARRE" << endl;

}

fonction virtuelleFigure-2.cpp

antislashn.orgC vers C++ 160

}};

int main(){

Carre c;Figure f1;Figure f2 = c;Figure *f3 = &c;Figure &rf = c;c.afficher();f1.afficher();f2.afficher();f3->afficher();rf.afficher();

}

f1 et f2 sont desinstances de Figure

Perte des informationspropre à Carre

Page 161: Passer du langage C au langage C++

Fonctions virtuelles

• La création d'une classe polymorphe implique l'initialisationd'un pointeur vptr vers une vtable de la classe

• Un appel comme f3->afficher()– en absence de fonction virtuelle aurait été traduit parFigure::afficher(f3)

– avec une fonction virtuelle il est traduit comme(*f3->vptrFigure[0])(f3)(*f3->vptrFigure[0])(f3)

• [0] car affiche() est la première fonction virtuelle

antislashn.orgC vers C++ 161

propriétés de Figure

vprtFigure

instance de Figure

&A::affiche

vtable de Figure

autres méthodesvirtuelles

Page 162: Passer du langage C au langage C++

Fonctions virtuelles

• Un objet n'est pas typé tant qu'il n'est pascomplètement construit

– un constructeur ne peut pas être virtuel

– l'appel d'une fonction virtuelle dans un constructeurn'a pas toujours l'effet escomptén'a pas toujours l'effet escompté

• Le destructeur peut-être virtuel

– ATTENTION : si le destructeur n'est pas virtuel ledestructeur de la classe fille ne sera pas appelé

antislashn.orgC vers C++ 162

Page 163: Passer du langage C au langage C++

Destructeur virtuel

class A{public:

A(){ cout << "++ CONSTRUCTEUR A()" << endl;}~A(){ cout << "-- DESTRUCTEUR ~A()" << endl;}

};

class B:public A{public:

B(){ cout << "++ CONSTRUCTEUR B()" << endl;}~B(){ cout << "-- DESTRUCTEUR ~B()" << endl;}

};

destructeur-virtuel.cpp

Destructeur nonvirtuel

antislashn.orgC vers C++ 163

};

int main(){A *pa = new B();delete pa;

}

Pas d'appel audestructeur de B

Page 164: Passer du langage C au langage C++

Classe abstraite

• Des fonctions peuvent être purement virtuelles

– pas d'implémentation fournie

– présente le vocabulaire de base

– syntaxe :virtual void nom_fonction() = 0;

• Une classe qui comporte au moins une fonctionvirtuelle pure est une classe abstraite

– pas de création d'instance

– une classe abstraite pure ne comporte que desfonctions virtuelles pures

antislashn.orgC vers C++ 164

Page 165: Passer du langage C au langage C++

Classe abstraite

• Exemple class Figure{public:

virtual void afficher() =0 ;};

class Point : public Figure{int x,y;

public :Point(int x, int y){this->x = x, this->y = y;}void afficher(){ cout << "Point en (" << x << "," << y << ")\n"; }

};class Carre : public Figure{

classe abstraite

Figure-3.cpp

antislashn.orgC vers C++ 165

class Carre : public Figure{Point xy;int cote;

public:Carre(int x, int y, int cote):xy(x,y) {this->cote = cote;}void afficher(){ cout <<"Carre cote : " << cote << endl; }

};int main(){

Carre *c = new Carre(1,2,3);Point *p = new Point(8,9);c->afficher();p->afficher();

}

Page 166: Passer du langage C au langage C++

Héritage multiple

• En C++ une classe peut hériter de plusieursclasses de base

– lors de l'initialisation de la classe B, l'ordre d'appel desconstructeurs correspond à l'ordre de déclaration desclasses de baseclasses de base

antislashn.orgC vers C++ 166

class A1{

};

class A2{

};

class B : public A1, public A2{

};

Page 167: Passer du langage C au langage C++

Héritage multiple

• Si les classes A1 et A2 sont elles même dérivéesd'une même classe de base, des ambigüitéspeuvent apparaitre

– les classes virtuelles permettent de solutionner cesambigüitésambigüités

• Forçage de type

• les valeurs de pa1 et pa2 sont différentes

antislashn.orgC vers C++ 167

B *pb = new B;A1 *pa1 = pb;A2 *pa2 = pb;

Page 168: Passer du langage C au langage C++

Héritage multiple

• Les membres d'une classe possèdent une portée– par dérivation de classe ou imbrication d'une classe dans

une autre

– à chaque niveau de dérivation est associée une portée, etun nom défini à ce niveau masque le même nom défini àun niveau supérieurun niveau supérieur

– ainsi avec l'héritage multiple il peut arriver qu'un mêmenom de fonction soit utilisé dans deux classes de base

• erreur de compilation lors de l'appel de la fonction

• le développeur peut préciser la classe de base utilisée

• certains compilateur permettent de mettre en place une clauseusing afin de changer la portée des fonctions

– il faut que les fonctions héritées aient des signatures différentes

antislashn.orgC vers C++ 168

Page 169: Passer du langage C au langage C++

Héritage multiple

• Exempleclass A1{

int i;public:

void f(int i) { cout << "A1::f(int)\n"; }};

class A2{int j;

heritage-multiple-1.cpp

antislashn.orgC vers C++ 169

int j;public:

void f(char c) { cout << "A2::f(char)\n"; }};

class B : public A1, public A2{using A1::f;using A2::f;

};

int main(){

B b;b.f(1);

}

clauses 'using' pour changerla portée des fonctions

appel de la fonction sansavoir besoin de préciser laclasse de base : b.A1::f(1);

Page 170: Passer du langage C au langage C++

Héritage multiple

• Empreinte mémoireclass A1{

char ta1[100];};

class A2{char ta2[100];

};

class B : public A1, public A2{char tb[100];

heritage-multiple-2.cpp

antislashn.orgC vers C++ 170

char ta1[100]

char ta2[100]

instance de B

sous instance A1

char tb[100];};

int main(){

cout << "Encombrement pour A1 : " << sizeof(A1) << endl;cout << "Encombrement pour A2 : " << sizeof(A2) << endl;cout << "Encombrement pour B : " << sizeof(B) << endl;

}

char tb[100]

sous instance A2

Page 171: Passer du langage C au langage C++

Héritage multiple

• Soit le schémas d'héritageclass A {...};class B1 : public A {...};class B2 : public A {...};class C: public B1, public B2 {...};

b1

aa

b2

c

– une instance de C comprend alors deux objets A

• occupation inutile de mémoire

• complication du codage

– la déclaration virtuelle de A dans la définition de B1 etB2 résout le problème

• il n'y aura qu'un objet a

antislashn.orgC vers C++ 171

Page 172: Passer du langage C au langage C++

Héritage multiple

• Sans déclaration virtual

class A{char a[100];

};

class B1:public A{char b1[100];

};

char a[100]

instance de A

char a[100] char a[100]

heritage-multiple-3.cpp

antislashn.orgC vers C++ 172

class B2:public A{char b2[100];

};

class C:public B1,public B2{char c[100];

};

char b1[100]

instance de B1

char b2[100]

instance de B2

char b1[100]

char a[100]

char b2[100]

instance de C

char c[100]

char a[100]

sous instance A de B1

sous instance A de B2

sous instance B1

sous instance B2

Page 173: Passer du langage C au langage C++

Héritage multiple

• Le code devient alorsclass A {...};class B1 : virtual public A {...};class B2 : virtual public A {...};class D: public B1, public B2 {...};

b1

a

b2

d

– le mécanisme d'appel des constructeurs est alorsmodifié

• le compilateur ignore les appels aux constructeurs de A quifigureraient dans une liste d'initialisation de B1 et B2

• on peut appeler les constructeurs de A dans une listed'initialisation de D

antislashn.orgC vers C++ 173

Page 174: Passer du langage C au langage C++

Héritage multiple

• Avec déclaration virtualclass A{

char a[100];};

class B1:virtual public A{char b1[100];

};

char a[100]

instance de A

char b2[100]

4 octets

char b1[100]

4 octets

antislashn.orgC vers C++ 174

class B2:virtual public A{char b2[100];

};

class C:public B1,public B2{char c[100];

};

instance de C

sous instance A

sous instance B1

sous instance B2

heritage-multiple-3.cpp

instance de B2

char a[100]

instance de B1

char a[100]

char b1[100]

char a[100]

4 octets

char b2[100]

4 octets

char c[100]

Page 175: Passer du langage C au langage C++

Classe – forme générale

• Forme générale

– un constructeur par défaut

• allocation de certaines parties de l'objet

– un destructeur

• désallocation des parties allouées dans le constructeur• désallocation des parties allouées dans le constructeur

– constructeur de copie

– opérateur d'affectation

antislashn.orgC vers C++ 175

class T{public:

T(…);T(const T&);~T();T& operator= (const T&);

};

Page 176: Passer du langage C au langage C++

Classe – forme générale

• Héritage et forme générale– classe de base T respectant la forme générale

• destructeur virtuel

• méthodes devant être redéfinies par les classes dérivées virtuelles

– classe dérivée U respectant la forme générale

antislashn.orgC vers C++ 176

class U :public T{public:

U(…);U(const U &x):T(x){

// recopie de la partie spécifique à U}~U();

U & operator=(const U & x){T *ad1 = this;T *ad2 = &x;*ad1 = ad2; // affectation de la partie héritée T// affectation de la partie non héritée

}};

Page 177: Passer du langage C au langage C++

Identification dynamique du type

• Le coût du polymorphisme est une indirectionsupplémentaire pour chaque appel de méthode– chaque objet à un encombrement supplémentaire

égal à la taille d'un pointeur, quelque soit le nombrede fonctions virtuellesde fonctions virtuelles

• Si un pointeur pointe sur un objet– on connait le type réellement pointé

• tout du moins le développeur le connait

– on connait le type du pointeur défini à la compilation

– il peut être souhaitable de voir l'objet pointé commel'objet concret, et non pas comme l'objet de base

antislashn.orgC vers C++ 177

Page 178: Passer du langage C au langage C++

Identification dynamique de classe

• Opérateur dynamic_cast

– syntaxe : dynamic_cast<type>(expression)

– permet la conversion d'une expression de typepointeur vers une autre

• si une classe de base A est dérivée en BA • si une classe de base A est dérivée en B– la conversion B* vers A* ne fait rien de plus que la conversion

standard

– la conversion A* vers B* n'a de sens que si le type concret pointéest bien de type B*

– l'opérateur dynamic_cast rend la conversion sure et portable

» rend l'adresse de l'objet si la conversion est possible

» renvoie NULL si la conversion n'est pas possible

antislashn.orgC vers C++ 178

A

B

Page 179: Passer du langage C au langage C++

Identification dynamique de classe

• Exemple sur dynamic_castclass A{

virtual void foo(){}};

class B1:public A{};class B2:public A{};

class B3{};

class C:public B1, public B2, protected B3{};

dynamic_cast.cpp

antislashn.orgC vers C++ 179

class C:public B1, public B2, protected B3{};

int main(void){

A *pa = new A;B1 *pb1 = new C;C *pc = new C;A &ra = *pa;// Vaut nullcout << "dynamic_cast<C *>(pa) : " << dynamic_cast<C *>(pa) << endl;// C dérive de B3 protected//cout << "dynamic_cast<B3 *>(pc) : " << dynamic_cast<B3 *>(pc) << endl;// Ambiguité : quel A ?//cout << "dynamic_cast<A *>(pc) : " << dynamic_cast<A *>(pc) << endl;cout << "dynamic_cast<C *>(pb1) : " << dynamic_cast<C *>(pb1) << endl;cout << "dynamic_cast<A *>(pb1) : " << dynamic_cast<A *>(pb1) << endl;cout << "dynamic_cast<B2 *>(pb1) : " << dynamic_cast<B2 *>(pb1) << endl;

}

ne passe pas à lacompilation

Page 180: Passer du langage C au langage C++

Identification dynamique de classe

• Opérateur typeid– permet de connaitre le véritable type d'un objet désigné par un

pointeur ou une référence– renvoie un objet de type type_info

• contient entre autre– une méthode name()

– les opérateur == et != pour la comparaison

antislashn.orgC vers C++ 180

int main(void){

D d;B &b = d;NV &nv = d;int i;B b1;

cout << typeid(b).name() << endl;cout << typeid(3.2).name() << endl;cout << typeid(nv).name() << endl;cout << typeid(d).name() << endl;cout << typeid(b1).name() << endl;

if(typeid(b)==typeid(d))cout << "type identique" << endl;

}

typeid.cpp

Page 181: Passer du langage C au langage C++

Pointeur sur membre de classe

• Il est courant de manipuler des fonctions autravers de pointeurs

– mécanisme du C

– transposé sur les classes en C++, cela revient àréférencer une fonction statique d'une classeréférencer une fonction statique d'une classe

antislashn.orgC vers C++ 181

class A{public:

static int doubler(int i) {return i*2;}};

int main(){

A a;int (*pf)(int);pf = A::doubler;cout << (*pf)(5) << endl;system("PAUSE");

}

pointeur versfonction

pointeur-membre-1.cpp

Page 182: Passer du langage C au langage C++

Pointeur sur membre de classe

• Pour un objet donné, il est toujours possible deréférencer par pointeur une donnée

– sous réserve de l'accessibilité

class A{public:

antislashn.orgC vers C++ 182

public:int i;int doubler(int i) {return i*2;}

};

int main(){

A a;int *pi = &a.i;

}

pointeur vers int

Page 183: Passer du langage C au langage C++

Pointeur sur membre de classe

• Mais il peut être utile de pouvoir manipuler desnotions plus abstraites– pointer sur une fonction membre non statique

– pointer sur une fonction de la classe ayant unargument de type int et retournant un doubleargument de type int et retournant un double

– pointer sur un champ de type int de la classe

• C++ met en place un syntaxe particulière pour cesnotions– syntaxe pouvant paraitre insolite

– le pointeur n'a pas son sens usuel : sa valeur n'est pasaccessible

antislashn.orgC vers C++ 183

Page 184: Passer du langage C au langage C++

Pointeur sur membre de classe

• Pointeur sur une donnée membre

– déclaration• type classe::*pointeur;

– initialisation• pointeur = &classe::donnee;• pointeur = &classe::donnee;

• Après l'initialisation le pointeur ne désigne pasd'adresse en mémoire

– il est associé à l'offset du champ dans l'objet

– il peut être utilisé ensuite sur un objet de la classe• objet.*pointeur;

antislashn.orgC vers C++ 184

Page 185: Passer du langage C au langage C++

Pointeur sur membre de classe

• Exemple de pointeur sur une donnée membre

using namespace std;

class A{public:

int i;A(int j){i=j;}

pointeur-membre-2.cpp

antislashn.orgC vers C++ 185

int doubler(int i) {return i*2;}};

int main(){

A a(20);int A::*pi = &A::i;cout << a.*pi << endl;system("PAUSE");

}

déclaration etinitialisation du pointeur

utilisation du pointeur

Page 186: Passer du langage C au langage C++

Pointeur sur membre de classe

• Pointeur sur une fonction membre– déclaration

• type_retour (class::*pointeur)(liste_type_arguments);

– initialisation• pointeur = &classe::fonction;

• Comme le cas précédent le pointeur ne contient• Comme le cas précédent le pointeur ne contientpas l'adresse– il ne peut être converti vers un pointeur vers fonction

au sens C

– il peut être utilisé par une instance de la classe• (objet.*pointeur)(liste_paramètres);

antislashn.orgC vers C++ 186

Page 187: Passer du langage C au langage C++

Pointeur sur membre de classe

• Exemple de pointeur sur une fonction membre

class A{public:

int i;A(int j){i=j;}int doubler(int i) {return i*2;}

};

pointeur-membre-3.cpp

antislashn.orgC vers C++ 187

int main(){

A a(20);A *pa = &a;int (A::*pf)(int) = &A::doubler;cout << (a.*pf)(56) << endl;cout << (pa->*pf)(56) << endl;system("PAUSE");

}

déclaration etinitialisation du pointeursur fonction membre

utilisation du pointeurvia l'instance

utilisation du pointeurvia un pointeur versl'instance

Page 188: Passer du langage C au langage C++

Les exceptions

• C++ définit un mécanisme de traitement deserreurs : les exceptions

• Une exception est levée par une instructionthrow

exception-1cpp

– un type quelconque peut être lancé dans l'exception

• possibilité de créer ses propres classes d'exception

antislashn.orgC vers C++ 188

void Point::exceptionPointNonValide(){

if(x<0 || y<0)throw "Point avec coordonnees negatives";

}

exception-1cpp

Page 189: Passer du langage C au langage C++

Les exceptions

• Un bloc try entoure le code susceptible de lancerune exception

• Un bloc catch permet de gérer l'exception

– peut être omis en fonction des compilateurs

• un gestionnaire par défaut est mis en place– termine le programme

– le type du paramètre du catch correspond au type del'exception levée

– plusieurs blocs catch peuvent être mis en place

• avec des signatures différentes

antislashn.orgC vers C++ 189

Page 190: Passer du langage C au langage C++

Les exceptions

• Exemple de traitement (extrait)

try{

Point p(-1,2);cout<<"tout c'est bien passe"<<endl;

}catch(char *m)

instruction susceptiblede lancer une exception

exception-1.cpp

antislashn.orgC vers C++ 190

{cout<<"ATTENTION : "<<m<<endl;

}catch(int m){

cout<<"Exception numero : "<<m<<endl;}

signature pour unpointeur vers char

signature pour un entier

Page 191: Passer du langage C au langage C++

Les exceptions

• Si l'exception n'est pas attrapée elle remonte à lafonction appelante

• Si l'exception remonte jusqu'au main alors lafonction terminate() est appelée

– possibilité de personnaliser en fournissant sa proprefonction à set_terminate

• Un catch peut aussi lever une exception

antislashn.orgC vers C++ 191

Page 192: Passer du langage C au langage C++

Les exceptions

• Une fonction peut indiquer le type d'exception qu'elle estsusceptible de lever– précise le contrat à l'intention des utilisateurs de la fonction

• si la fonction lance une exception non prévue la fonction unexpectedest alors appelée

– le comportement personnalisé en fournissant à la fonction set_unexpected sonpropre gestionnaire

– syntaxe :– syntaxe :en_tête_fonction throw(type, type,…)• si aucun type n'est précisé, cela indique que la fonction ne peut lancer

aucune exception• une fonction dont la clause throw(…) n'est pas précisé peut lever tout

type d'exception

– cette fonctionnalité n'est pas présente sur tous lescompilateurs

• le mécanisme des exceptions fonctionne mais pas le unexpected

antislashn.orgC vers C++ 192

Page 193: Passer du langage C au langage C++

Les exceptions

• Fonctions terminate et unexpected

– unexpected n'est pas supportée par tous lescompilateurs typedef void (*handler)();

handler set_terminate(handler);handler set_unexpected(handler);

antislashn.orgC vers C++ 193

void exceptionNonTraitee(){

cout << "ERREUR" << endl;exit(EXIT_FAILURE);

}int main(){

set_terminate(exceptionNonTraitee);Point p(-1,2);cout<<"tout c'est bien passe"<<endl;

}exception-2.cpp

Page 194: Passer du langage C au langage C++

Les exceptions

• Une exception est une valeur quelconque

• Les fonctions de la bibliothèque peuvent leverdes exceptions

– ces exceptions sont dérivées d'une classe commune,la classela classe exception

• 3 types dérivés directement ou indirectement– les exceptions : bad_exception, bad_cast, bad_typeid, …

– bad_alloc

– les runtime_error : range_error, overflow_error,underflow_error

antislashn.orgC vers C++ 194

Page 195: Passer du langage C au langage C++

Les exceptions

• Lors d'une exception les instructions placée entre lepoint où est lancée l'exception et celui où elle estattrapée sont abandonnées– cela ce traduit par la terminaison immédiate des fonctions

• la pile d'exécution est décapitée

• les espaces locaux sont perdus• les espaces locaux sont perdus

• les allocations ne sont pas libérées

– C++ garanti que les destructeurs des objets locaux auxfonctions sont appelés

• on peut alors utiliser une classe spécifique gérant les pointeurs etles allocations / désallocations mémoire

– cf. les smart pointer

antislashn.orgC vers C++ 195

Page 196: Passer du langage C au langage C++

Les exceptions

• Flux normal d'appel méthode A

méthode B méthode C

antislashn.orgC vers C++ 196

• Flux exceptionnelméthode A

méthode B méthode C

levéed'exception

code nonexécuté

Page 197: Passer du langage C au langage C++

Espaces de noms

• Un espace de noms permet d'éviter les collisionsde nommage sur des bibliothèques différentes

– les entités de la bibliothèque standard appartiennentà l'espace de noms std

espace de nom utilisé par

antislashn.orgC vers C++ 197

using namespace std;

namespace perso{class X{};class Y{};

}

int main(){

perso::X x;}

espace de nom utilisé pardéfaut

définition d'un espace denoms

utilisation de la classe X

namespace.cpp

Page 198: Passer du langage C au langage C++

Espaces de noms

• Les espaces de noms peuvent être imbriqués

– exemples pour .h et .cpp#ifndef __POINT_H__#define __POINT_H__

namespace antislashn{namespace formes{

class Point

namespace antislashn{namespace formes{

Point::Point(int x){

…}

antislashn.orgC vers C++ 198

class Point{

private :int x,y;

public :void afficher();Point();Point(const Point &);Point(int);Point(int,int);

};}

}#endif

}

…void Point::afficher(){

…}

}

Page 199: Passer du langage C au langage C++

Espaces de noms

• Utilisation des namespaces imbriqués#include "Point.h"#include <iostream>

using namespace antislashn::formes;int main(){

Point p = (Point)8;p.afficher();

• Convention possible : utilisation des chemins desfichiers, façon "packages java"

antislashn.orgC vers C++ 199

Point p1 = p;

Point * pt = new Point(6);p.afficher();pt->afficher();delete pt;

::std::cout<<"FIN\n";}

Page 200: Passer du langage C au langage C++

Espaces de noms

• Utilisation partielle des espaces de nom– de manière générale

::[namespace::] identificateur::antislashn::formes::Point

[namespace::] identificateurformes::Pointformes::Point

• L'éventuel premier :: indique la région déclarativeglobale– une expression commençant par :: est interprétée

comme absolue

– une expression ne commençant pas par :: estinterprétée comme relative

antislashn.orgC vers C++ 200

Page 201: Passer du langage C au langage C++

Espaces de noms

• Aliasnamespace alias = espaceDeNoms;

– introduit un alias pour une espace de nommage donné• réduction d'un espace de noms particulièrement long

• paramétrage d'un espace de noms

• Espace anonyme• Espace anonyme– directive namespace sans nom

– identificateur unique pour chaque unité de compilation• équivaut à des déclarations statiques au niveau globale

• l'emploie des espaces de noms anonyme est préférable à celui duqualificateur static

– autres significations dans d'autres contextes : membres de classe,variables locales statiques

antislashn.orgC vers C++ 201

Page 202: Passer du langage C au langage C++

Bibliothèque standard

• Ensemble de librairies définies par la norme ISO– bibliothèque regroupée dans 32 fichiers d'en-tête

• support du langage

• diagnostics

• utilitaires généraux

• chaînes de caractères• chaînes de caractères

• localisation

• composants numériques

• flux d'entrée / sortie (IO Stream Library)

• Standard Template Library– conteneurs

– itérateurs

– algorithmes

antislashn.orgC vers C++ 202

Page 203: Passer du langage C au langage C++

Bibliothèque standard

• Sauf les macros et opérateurs new et delete, tousles éléments sont membres de l'espace standardstd, ou d'espaces imbriqués dans std

• Les éléments de la bibliothèque standard C peuventêtre utilisés– déclarés dans 18 fichiers commençant par c– déclarés dans 18 fichiers commençant par c

• <cassert>, <cctype>, <cerrno>, <cfloat>, …– au lieu de <assert.h>, <ctype.h>, <errno.h>, <float.h>, …

– les fonctions C appartiennent au namespace global, cellede C++ appartiennent au namespace std

• double sin(double) de math.h appartient au namespaceglobal

• double std::sin(double) de cmath.h appartient aunamespace std

antislashn.orgC vers C++ 203

Page 204: Passer du langage C au langage C++

Bibliothèque standard

• On y trouve toutes les fonctions prévues dans lesversions C++ d'avant la norme de 1998

• Plus un ensemble de patron de classes etfonctions provenant d'une bibliothèque publiquenommée la Standard Template Library (STL)nommée la Standard Template Library (STL)

– développée à l'origine chez Hewlett Packard

antislashn.orgC vers C++ 204

Page 205: Passer du langage C au langage C++

Support du langage

• Fichiers d'en-tête– <cstddef> définit les types dépendant de l'implémentation

• size_t type entier le mieux adapté pour le résultat de sizeof• ptrdiff_t type entier le mieux adapté au résultat de la soustraction de

deux pointeurs

– propriétés de l'implémentation : <limits>, <climits>, <cfloat>– démarrage et terminaison des programmes : <cstdlib>– démarrage et terminaison des programmes : <cstdlib>– gestion dynamique de la mémoire : <new>– identification dynamique des types : <typeinfo>

• pour les dynamic_cast<type>

– gestion des exceptions : <exception>– autres fonctions du runtime :

• <cstdarg> : nombre variables d'arguments• <csetjmp> : "goto" inter fonctions• <ctime> : horloge machine• <csignal> : détection des événements asynchrones

antislashn.orgC vers C++ 205

Page 206: Passer du langage C au langage C++

Chaînes de caractères

• Fichiers d'en-tête

• En C une chaine de caractères est un tableau decaractères dont le dernier élément est le caractèrenull

<string> <cstdlib>

<cstring> <cctype> <cwtype> <cwchar>

caractères dont le dernier élément est le caractèrenull– utilisation de char[] et char *

• En C++ une chaine est un ensemble ordonné decaractères– s'apparente à un vector

– fournit le support pour les caractères ASCII (char) etcaractères étendus (wchar_t)

antislashn.orgC vers C++ 206

Page 207: Passer du langage C au langage C++

Chaînes de caractères

• La classe basic_string utilise un vecteur pourordonner les caractères

– la longueur de la chaîne est variable

– l'accès aux caractères n'est plus aussi directe que pourun tableauun tableau

• des méthodes spécifiques sont ajoutées pour travailler surles intervalles de caractères

• La classe string spécialise basic_string pourles caractères de type char

– améliore grandement l'utilisation par rapport à char *

antislashn.orgC vers C++ 207

Page 208: Passer du langage C au langage C++

Chaînes de caractères

• Constructeurs

– les chaînes se construisent de différentes manières

• à partir d'une chaîne C (char *)

• avec une chaîne littérale

• à partir d'une autre chaîne• à partir d'une autre chaîne

• à partir d'une sous chaîne

• …

antislashn.orgC vers C++ 208

Page 209: Passer du langage C au langage C++

Chaînes de caractères

• Constructeurs

– exemplesint main(int args, char* argv[]){

string s1; // chaine videstring s2 = ""; // chaine videstring s3 = "Hello";

begin() et end()renvoient uneréférence versun caractère, et

antislashn.orgC vers C++ 209

string s3 = "Hello";string s4(s3); // copie s3 dans s4

// copie tous les caractères de s3 dans s5string s5(s3.begin(),s3.end());// copie tous les caractères de s3 dans s5string s6(s3,0,s3.length());

}

un caractère, etnon pas unindice entier

string-1.cpp

Page 210: Passer du langage C au langage C++

Chaînes de caractères

• Accès aux éléments

– par un itérateur et un itérateur inverse

• itérateur string::iterator par begin() et end()

• itérateur inverse string::reverse_iterator parrbegin() et rend()rbegin() et rend()

– par l'operateur index [] surchargé par la classe string

antislashn.orgC vers C++ 210

string s = "Hello world";for(string::iterator it = s.begin() ; it!=s.end() ; it++)

cout << *it;

for(int i=0 ; i<s.length() ; i++)cout << s[i];

string-2.cpp

string-2.cpp

Page 211: Passer du langage C au langage C++

Chaînes de caractères

• Comparaisons

– la méthode compare() retourne le même résultatque le ferait la fonction strcmp()

– les opérateurs == , != , < , <= , > , >= ont étésurchargéssurchargés

antislashn.orgC vers C++ 211

Page 212: Passer du langage C au langage C++

Chaînes de caractères

• Méthodes disponibles sur la classe string pourconvertir vers char * du langage C– data() copie la chaîne de caractères C++ vers un tableau

avant de retourner un pointeur (const char *)• l'instance de string se charge de désallouer le tableau

– ne pas tenter de le faire !!!– ne pas tenter de le faire !!!

• la chaîne ne peut pas être modifiée– le tableau appartient à l'instance de string

– c_str() fonctionne comme data() en ajoutant unnull final

– copy() recopie le contenu de la chaîne dans un bufferfournit par le développeur

• le développeur doit désallouer ce buffer

antislashn.orgC vers C++ 212

Page 213: Passer du langage C au langage C++

Chaînes de caractères

• Ajout de chaîne en fin de chaîne par surcharge del'opérateur +=

– même fonctionnalité que la méthode append()string s = "Hello";s += " world";

string-3.cpp

• Insertion de chaîne par la méthode insert()

• Concaténation par l'opérateur +

antislashn.orgC vers C++ 213

s.insert(6,"!!! ");

s = s + "\tBonjour tout le monde";

string-3.cpp

Page 214: Passer du langage C au langage C++

Chaînes de caractères

• Méthodes de recherche et remplacement

– find() recherche une sous-chaine

– rfind() recherche une sous-chaîne en partant de lafin

– recherche de caractères– find_first_of() recherche de caractères

– find_last_of() recherche de caractères en partantde la fin

– replace() remplace une partie de la chaîne

– erase() supprime un certain nombre de caractères

– substr() extrait une sous-chaîne

antislashn.orgC vers C++ 214

Page 215: Passer du langage C au langage C++

Diagnostics

• Composants signalant les erreurs à l'exécutionregroupés dans les en-têtes

– <stdexcept>

– <cassert>

– <cerrno>– <cerrno>

antislashn.orgC vers C++ 215

Page 216: Passer du langage C au langage C++

Localisation

• Fichier en-tête <locale> utilisé pour lalocalisation

– fonctions sur les caractères de type isxxxx

• isspace, isupper, …

– date et heure– date et heure

– symboles et monétaires

– obtention de chaînes de caractères depuis lecatalogue de messages

antislashn.orgC vers C++ 216

Page 217: Passer du langage C au langage C++

Les outils numériques

• Fichiers d'en-tête concernés

• complex déclare un modèle pour l'utilisation desnombres complexes

<complex> <valarray> <numeric> <cmath> <cstdlib>

nombres complexes

– constructeurs

– comparaisons, opérations arithmétiques

– forme polaire

antislashn.orgC vers C++ 217

Page 218: Passer du langage C au langage C++

Les outils numériques

• valarray et les classes associées permettent lamanipulation des vecteurs (au sensmathématique du terme)

– possibilité de calcul vectoriel comparable aux langagesscientifiquesscientifiques

– manipulation vectorielle des types numériques• bool, char, int, float, double, complex

– chaque opération (binaire ou unaire) sur le typenumérique induit une opération (binaire ou unaire)sur les valarray

antislashn.orgC vers C++ 218

Page 219: Passer du langage C au langage C++

Flux d'entrée - sortie

• Un flux est un contenu lu ou écrit par une partie del'application– plus abstrait qu'un fichier qui est caractérisé par un nom,

un emplacement, droits d'accès, …

– l'information lue ou écrite peut-être de plus ou moinshaut niveau : octet, entier, décimal, chaine, …haut niveau : octet, entier, décimal, chaine, …

• les flux sont organisés en 3 niveaux– le plus abstrait : ios_base

– basic_ios qui intègre la notion de localisation

– basic_iostream qui regroupe les classes destinées àsupporter le formatage des types de base connus par C++

• c'est à ce niveau que nous travaillons

antislashn.orgC vers C++ 219

Page 220: Passer du langage C au langage C++

Flux d'entrée - sortie

• Relations d'héritage entre les flux

ios_base

ios

streambuf

stringbuf filebuf

antislashn.orgC vers C++ 220

istream ostream

istringstream ifstream ostringstream ofstreamiostream

stringstream fstream

Page 221: Passer du langage C au langage C++

Flux d'entrée - sortie

• L'utilisation classique des flux passe par lamanipulation des flux standards

– cout, cin, cerr

• et des classes

– istream et ostream

• Les opérateurs d'insertion << et d'extraction >>sont utilisés pour lire et écrire les types de base

– il est possible d'enrichir les types supportés par lasurcharge des opérateurs à l'aide d'une fonction amie

antislashn.orgC vers C++ 221

Page 222: Passer du langage C au langage C++

Flux – la classe ostream

• L'opérateur << est surchargé pour les différentstypes de baseostream & operator << (expression)

• insertion dans un flux

• reçoit deux opérandes• reçoit deux opérandes– l'instance l'ayant appelé (argument implicite this)

– une expression d'un type de base

• son rôle est de transmettre l'expression au flux en laformatant de façon appropriée

• retourne la référence au flux concerné– permet le chainage

antislashn.orgC vers C++ 222

Page 223: Passer du langage C au langage C++

Flux – la classe ostream

• Il existe dans iostream des fonctions membres– écriture d'un caractère

• ostream &put(char c);

– écriture du contenu d'un buffer• ostream &write(const char *s, int n);• envoie de n caractères• envoie de n caractères• permet l'envoie du caractère null, contrairement à <<

– flush du buffer• ostream &flush();

– positionnement• int tellp();• ostream &seek(int p);• ostream &seek(int o, ios_base::seekdir dir);

antislashn.orgC vers C++ 223

Page 224: Passer du langage C au langage C++

Flux – la classe ostream

• Quelques possibilités de formatage avec <<

– des manipulateurs permettent de formater le flux desortie

int main(void){

int n = 122;

– actions possibles sur le gabarit, précision, choixnotation flottant exponentiel, …

antislashn.orgC vers C++ 224

int n = 122;cout << "par defaut : " << n << endl;cout << "en hexa : " << hex << n << endl;cout << "en decimal : " << dec << n << endl;cout << "en octal : " << oct << n << endl;

}

Page 225: Passer du langage C au langage C++

Flux – la classe istream

• L'opérateur >> est surchargé pour les différentstypes de baseistream & operator >> (type_de_base &)

• extraction depuis un flux

• reçoit deux opérandes– l'instance l'ayant appelé (argument implicite this)

– une lvalue d'un type de base

• son rôle est d'extraire du flux les caractères nécessairespour former une valeur du type de base voulu en réalisantune opération de inverse du formatage opéré parl'opérateur <<

• retourne la référence au flux concerné– permet le chainage

antislashn.orgC vers C++ 225

Page 226: Passer du langage C au langage C++

Flux – la classe istream

• Comme pour ostream, il existe des fonctionsmembres dans iostream qui permettent

– la lecture de caractères ou de séquences de caractères

• fonctions get

– lectures facilitant la lectures de chaine de caractères– lectures facilitant la lectures de chaine de caractères

• fonctions getline, gcount

– fonctions de gestion du buffer

• fonctions tellg, seek, unget, …

antislashn.orgC vers C++ 226

Page 227: Passer du langage C au langage C++

Flux – connexion à un fichier

• Fichier en sortie

– création d'une instance de ofstream

• nécessite l'inclusion de <fstream>

• le constructeur nécessite– le nom du fichier– le nom du fichier

• la manipulation du flux se fait comme pour n'importe quelflux de type ostream

antislashn.orgC vers C++ 227

ofstream outFile("c:\\test.dat");if(outFile.is_open()){

outFile << "Hello " << 10 << endl;outFile.close();

}

Page 228: Passer du langage C au langage C++

Flux – connexion à un fichier

• Fichier en entrée

– création d'une instance de ifstream

• nécessite l'inclusion de <fstream>

• le constructeur nécessite– le nom du fichier– le nom du fichier

• la manipulation du flux se fait comme pour n'importe quelflux de type istream

antislashn.orgC vers C++ 228

ifstream inFile("c:\\test.dat");if(inFile.is_open()){

string s;int n;inFile >> s >> n;cout<< s <<" " <<n << endl;inFile.close();

}

Page 229: Passer du langage C au langage C++

C++11 – smart pointers

• Utilisation du mécanisme de la pile pour libérer lamémoire

– le smart pointer encapsule un pointeur référençant unobjet sur le tas

– lorsque le smart pointer est supprimé de la pile, son– lorsque le smart pointer est supprimé de la pile, sondestructeur est appelé, celui-ci désalloue la mémoireréférencée par la pointeur interne

• Les smart pointers sont implémentés sous formede template

• librairie memory

antislashn.orgC vers C++ 229

Page 230: Passer du langage C au langage C++

C++11 - smart pointer

• Exemple de fonctionnement d'un smart pointertemplate<class T> class SmartPointer{

T *pointeur;SmartPointer(const SmartPointer& a){}void operator=(const SmartPointer& a){}

public:SmartPointer(T* ptr):pointeur(ptr){cout << "++++" << endl;}

antislashn.orgC vers C++ 230

SmartPointer(T* ptr):pointeur(ptr){cout << "++++" << endl;}

~SmartPointer(){cout << "----" << endl;delete pointeur;

}

T& operator*() { return *pointeur; }T* operator->() { return pointeur; }

};

Page 231: Passer du langage C au langage C++

C++11 - smart pointer

• unique_ptr

– ne partage pas son pointeur sous-jacent

– ne peut pas être copié, ni passé à un fonction, niutilisé dans un algorithme de la STL

antislashn.orgC vers C++ 231

source illustration : msdn

Page 232: Passer du langage C au langage C++

C++11 – smart pointer

• shared_ptr

– permet le partage d'un pointeur

– contient un compteur de référence

– le pointeur sous-jacent n'est pas supprimé tant quetous les propriétaires ne sont pas hors de portéetous les propriétaires ne sont pas hors de portée

antislashn.orgC vers C++ 232

source illustration : msdn

Page 233: Passer du langage C au langage C++

C++11 – smart pointer

• weak_ptr

– s'utilise avec shared_ptr

– permet de fournir l'accès au pointeur sous-jacent,sans participer au comptage de référence

antislashn.orgC vers C++ 233

Page 234: Passer du langage C au langage C++

STL – conteneur, itérateur et algorithme

• Les notions de conteneur, itérateur et algorithmesont étroitement liées– interviennent simultanément dans un programme utilisant

les conteneurs

• Conteneur• Conteneur– ensemble de classes permettant de représenter les

structures de données ordonnées• vecteurs, listes, ensembles, tableaux associatifs

– patrons de classes paramétrés par le type de leurséléments

• list <int> li;

• vector <Point> lp;

antislashn.orgC vers C++ 234

Page 235: Passer du langage C au langage C++

STL – conteneur, itérateur et algorithme

• Itérateur– l'itérateur permet de standardiser les actions sur un

conteneur

– permet de parcourir, comparer, manipuler leséléments d'un conteneuréléments d'un conteneur

• sans avoir à ce préoccuper de la structure interne duconteneur

– liste chainée, doublement chainée, liste de tableaux, etc.

• permet au minimum un parcours unidirectionnel– par ++

– différents types d'itérateurs :• unidirectionnel, bidirectionnel, à accès direct

antislashn.orgC vers C++ 235

Page 236: Passer du langage C au langage C++

STL – conteneur, itérateur et algorithme

• Parcours d'un conteneur avec un itérateur

– parcours direct

• les conteneurs fournissent des valeurs particulièresd'itérateur via des méthodes begin() et end()

• ceci permet d'avoir un modèle de parcours standard• ceci permet d'avoir un modèle de parcours standard

antislashn.orgC vers C++ 236

list<int> entiers;list<int>::iterator it;for(it = entiers.begin() ; it != entiers.end() ; it++){

// traitement quelconque sur *it}

Page 237: Passer du langage C au langage C++

STL – conteneur, itérateur et algorithme

• Parcours d'un conteneur avec un itérateur

– parcours inverse

• certains conteneurs fournissent des itérateursbidirectionnels

– on peut appliquer les opérateur ++ et --– on peut appliquer les opérateur ++ et --

• ces conteneurs fournissent– un second itérateur reverse_iterator

– les méthodes

» rbegin() qui pointe sur le dernier élément du conteneur

» rend() qui pointe juste avant le premier élément

antislashn.orgC vers C++ 237

list<int> entiers;list<int>::reverse_iterator rit;for(rit = entiers.rbegin() ; rit != entiers.rend() ; rit++){

// traitement quelconque sur *rit}

Page 238: Passer du langage C au langage C++

STL – conteneur, itérateur et algorithme

• Intervalle d'itérateur

– les conteneurs sont ordonnés

– on peut préciser un intervalle d'itérateur en précisantles bornes sous forme de valeur d'itérateur

• vector<Point>::iterator it1, it2;• vector<Point>::iterator it1, it2;

• si it1 et it2 possèdent des valeurs telles que it2 soitaccessible depuis it1

– c'est-à-dire qu'un certain nombre d'incrémentation it1++ permetd'obtenir la valeur de it2

• alors les valeurs it1 et it2 définissent un intervalle

antislashn.orgC vers C++ 238

Page 239: Passer du langage C au langage C++

STL – conteneur, itérateur et algorithme

• Algorithme

– par le biais des itérateurs beaucoup d'opérationspeuvent être appliquées au conteneur

• quelque soit la nature du conteneur

• quelque soit le type de l'élément• quelque soit le type de l'élément

– par exemple : trouver le premier élément ayant unevaleur donnée

• il faut que l'égalité entre les éléments soit convenablementdéfinie

– surcharge de l'opérateur ==

antislashn.orgC vers C++ 239

Page 240: Passer du langage C au langage C++

STL – conteneur, itérateur et algorithme

• Algorithme

– les différents algorithmes sont fournis sous forme depatron de fonctions

• paramétrés par le type des itérateurs

• exemple : comptage du nombre d'élément valant 1• exemple : comptage du nombre d'élément valant 1

– ce même modèle de code est réutilisable sur une liste, sur destypes différents

antislashn.orgC vers C++ 240

vector<int> entiers;int nb = count(entiers.begin(),entiers.end(),1);

Page 241: Passer du langage C au langage C++

STL – conteneur, itérateur et algorithme

• Les conteneurs se différencient entre eux parleurs caractéristiques– celles-ci doivent être indépendantes de

l'implémentation

– se différencient aussi par l'efficacité de certaines– se différencient aussi par l'efficacité de certainesopérations

• La norme classe les conteneurs en– conteneurs en séquences (conteneurs séquentiels)

– conteneurs associatifs

• les éléments d'un conteneur sont ordonnés

antislashn.orgC vers C++ 241

Page 242: Passer du langage C au langage C++

STL – Conteneurs

• Construction d'un conteneur– la construction d'un conteneur d'objets non vide dont les

éléments sont des objets entraine, pour chaque élément• soit l'appel d'un constructeur

– construction d'un vecteur de 3 points

• soit l'appel d'un constructeur par recopie

vector<Point> v(3);

vector<Point> w(v);• soit l'appel d'un constructeur par recopie– construction d'un vecteur à partir d'un autre

» appel du constructeur par recopie de vector<Point> qui appelle leconstructeur par recopie de Point

– une construction par affectation• peut appeler l'opérateur d'affectation si la taille de w est

suffisante

• ou destruction de w et recopie de v si la taille de w estinsuffisante

antislashn.orgC vers C++ 242

vector<Point> w(v);

w = v;

Page 243: Passer du langage C au langage C++

STL – Conteneurs

• Attention, le passage d'un conteneur en tantqu'argument de fonction est effectué par valeur

– il y a donc recopie de tous les éléments du conteneur

– préférez le passage par référence

Certaines opérations sur les conteneurs peuvent• Certaines opérations sur les conteneurs peuventaussi appeler des méthodes de la classe élément

– recherche, comparaison, …

antislashn.orgC vers C++ 243

Page 244: Passer du langage C au langage C++

STL – algorithmes : fonctions, prédicats etclasses fonctions• Fonction unaire

– permet d'appliquer une fonction aux différentséléments d'une séquence

• la séquence correspond à un intervalle d'itérateurs

• cette fonction est alors passée en argument de l'algorithmecette fonction est alors passée en argument de l'algorithme

– f doit posséder un argument du type des éléments

– l'éventuelle valeur de retour n'est pas utilisée

• Prédicat– fonction qui retourne une valeur de type bool

– utilisée par certains algorithmes comme find_if

antislashn.orgC vers C++ 244

for_each(it1, it2, f);

find_if(it1,it2, f);

Page 245: Passer du langage C au langage C++

STL – algorithmes : fonctions, prédicats etclasses fonctions• Certains algorithmes ou fonctions membres

nécessitent un prédicat comme argument– fonction callback

• Cette fonction est en général prévue dans ladéfinition du patron, sous forme d'un objet de typedéfinition du patron, sous forme d'un objet de typequelconque

• Classes fonctions prédéfinies dans <functional>– par exemple less(int) instancie une fonction patron

correspondant à la comparaison par < de deux int• patrons existants pour les opérateurs

– equal_to pour ==, not_equal_to pour !=, greater pour >, lesspour <, greater_equal pour >= et less_equal pour <=

antislashn.orgC vers C++ 245

Page 246: Passer du langage C au langage C++

STL – relation d'ordre

• Il est parfois nécessaire de connaitre une relation permettantd'ordonner les éléments d'un conteneur– pour des questions d'efficacité les éléments d'un conteneur

associatif sont ordonnés– tri sur certains conteneur

• Il faut redéfinir l'opérateur < qui est utilisé comme relationnaturellenaturelle

• Générateur d'opérateur– on peut théoriquement redéfinir les opérateurs == et !=

• de même pour <, <=, >, >=

– la STL dispose de patrons de fonctions permettant de définir• l'opérateur != à partir de ==• les opérateurs >, >= et <= à partir de <

– il suffit donc de munir une classe des opérateurs == et < pour qu'elledispose des autres

antislashn.orgC vers C++ 246

Page 247: Passer du langage C au langage C++

STL – Conteneurs séquentiels

• Conteneurs séquentiels– vector

• généralise la notion de tableau• iterateur à accès direct

– list• liste doublement chainéesliste doublement chainées• itérateur bidirectionnel

– deque• classe intermédiaire

• Adaptateurs de conteneur– stack– queue– priority_queue

antislashn.orgC vers C++ 247

Page 248: Passer du langage C au langage C++

STL – Conteneurs séquentiels

• Fonctionnalités communes

– construction

• conteneur vide

• avec un nombre d'éléments donné

vector<Point> v;

vector<Point> v(3);

• avec un nombre donné d'éléments initialisés

• à partir d'une séquence

• à partir d'un autre conteneur du même type

antislashn.orgC vers C++ 248

vector<Point> v(3);

Point p(1,2);list<Point> lp(10,p);

list<Point>lpi(lp.begin(),lp.end());

list<Point> lpi2(lpi);

Page 249: Passer du langage C au langage C++

STL – Conteneurs séquentiels

• Fonctionnalités communes

– modifications globales

• affectation

• méthode assign

vector<Point> v1(…) v2(…);v1 = v2;

• méthode assign

– permet de travailler entre conteneurs de types différents

• méthode clear : vide le conteneur

• méthode swap : échange le contenu de deux conteneurs

antislashn.orgC vers C++ 249

vector<Point> v1(…);list<Point> l1(…);Point p(…);l1.assign(10,p);l1.assign(v1.begin(),v1.end());

types de conteneurdifférents

10 élements avec valeur p

Page 250: Passer du langage C au langage C++

STL – Conteneurs séquentiels

• Fonctionnalités communes– comparaison de conteneur

• opérateur ==– si c1 et c2 sont deux conteneurs du même type c1 == c2 sera

vrai s'ils sont de même taille et si les éléments de même rang sontégauxégaux

• opérateur <– effectue une comparaison lexicographique des deux conteneurs

– compare les éléments du même rang avec l'opérateur < ets'interrompt si

» la fin d'un des conteneur est atteinte

» la comparaison entre deux éléments est fausse

• les opérateurs !=, <=, > et >= sont également disponibles

antislashn.orgC vers C++ 250

Page 251: Passer du langage C au langage C++

STL – Conteneurs séquentiels

• Fonctionnalités communes

– insertion d'éléments• insert(position, valeur)

• insert(position, nb_fois, valeur)

• insert(debut_intervalle,fin_intervalle,position)

– suppression d'éléments• erase(position)

• erase(debut_intervalle,fin_intervalle)

antislashn.orgC vers C++ 251

Page 252: Passer du langage C au langage C++

STL - vector

• Reprends la notion de tableau

– accès direct avec la même efficacité quelque soit lenombre d'éléments

– la taille peut varier en cours d'exécution

• Accès aux éléments• Accès aux éléments

– par itérateur

– par indice, via l'opérateur []

– accès au dernier élément, méthode back()

antislashn.orgC vers C++ 252

vector<int> v(10);v.back() = 33;

Page 253: Passer du langage C au langage C++

STL - vector

• Insertions et suppressions

– efficacité réduite avec erase et insert

• en C(n) pour les vecteurs, en C(1) pour les listes

– efficacité en C(1) en fin• insertion en fin, méthode push_back(valeur)• insertion en fin, méthode push_back(valeur)

• suppression en fin, méthode pop_back()

antislashn.orgC vers C++ 253

Page 254: Passer du langage C au langage C++

STL - vector

• Gestion mémoire– la norme n'impose pas d'implémentation– elle impose des contraintes d'efficacité– certaines opérations sur les vecteurs entrainent l'invalidation

des itérateurs ou références sur des éléments• augmentation de taille• insertion d'un élément• insertion d'un élément• certaines suppressions d'éléments

– méthodes outils :• size() : nombre d'éléments• capacity() : taille potentielle d'un vecteur• reserve(taille) : impose une taille minimale• max_size() : taille maximale allouable au vecteur• resize(taille) : modifie la taille

antislashn.orgC vers C++ 254

Page 255: Passer du langage C au langage C++

STL - deque

• Offre des fonctionnalités voisine de vector– accès direct aux éléments avec un complexité C(1)

• Ajoute une insertion et suppression au début– également en C(1)

• Une opération sur un deque sont moins rapide que lamême opération sur un vectormême opération sur un vector

• On ne dispose pas de capacity() et reserve()• Accès au premier élément par front()• Suppression du premier élément par pop_front()• Insertion d'un premier élément parpush_front(valeur)

antislashn.orgC vers C++ 255

Page 256: Passer du langage C au langage C++

STL - list

• Concept de liste doublement chainée

– itérateur bidirectionnel

– insertions et suppressions efficaces quelle que soit laposition

– pas d'itérateur à accès direct– pas d'itérateur à accès direct

• les itérateurs peut être manipulés avec ++ et --, mais pas depossibilité d'incrémentation avec une valeur quelconque

• obligation de parcourir la liste depuis le début

– list dispose de front() et back(), comme pour laclasse deque

antislashn.orgC vers C++ 256

Page 257: Passer du langage C au langage C++

STL - list

• Insertions et suppressions

– les fonctionnalités générales possèdent unecomplexité C(1)

– possibilité d'utiliser push_front(valeur),push_end(valeur), pop_front() et pop_end()push_end(valeur), pop_front() et pop_end()

– suppression de tous les éléments d'une valeur donnéepar remove(valeur)

– suppression par prédicat par remove_if(predicat)

antislashn.orgC vers C++ 257

int t[] = {1,2,1,3,1,4,1,5};list<int> li(t,t+8);li.remove(1);

bool isPaire(int i) {return !(i%2);…li.remove_if(isPaire);

Page 258: Passer du langage C au langage C++

STL - list

• Opérations globales : en plus des fonctionscommunes

– tri par sort()

– suppression des doublons par unique()

fusion de deux listes par– fusion de deux listes par merge()

– transfert entre une partie d'une liste dans une autrepar splice(debut_sequence,fin_sequence)

• Gestion mémoire

– on ne retrouve aucune fonction permettant d'agir surles allocations, comme capacity et reserve

antislashn.orgC vers C++ 258

Page 259: Passer du langage C au langage C++

STL – les adaptateurs de conteneur

• Trois patrons queue, stack et priority_queue

• Classes construites sur un conteneur pourl'adapter à des fonctionnalités spécifiques

– disposent toutes d'un constructeur par défaut

• Patrontype_adaptateur <type_element, type_conteneur>

antislashn.orgC vers C++ 259

Page 260: Passer du langage C au langage C++

STL - stack

• Gestion des piles LIFO– construction sur vector, list ou deque

– méthodes

stack<int, vector<int> > s1;stack<int, deque<int> > s2;stack<int, list<int> > s3;

– méthodes• empty() : true si la pile est vide

• size() : nombre d'éléments dans la pile

• top() : accès à la donnée au sommet – consultation oumodification

• push(valeur) : ajout d'un élément sur la pile

• pop() : supprime la valeur au sommet de la pile

antislashn.orgC vers C++ 260

Page 261: Passer du langage C au langage C++

STL - queue

• Gestion de file d'attente FIFO– construction sur list ou deque

• vector n'est pas approprié car pas d'accès en début

– méthodes

queue<int, deque<int> > q1;queue<int, list<int> > q2;

– méthodes• empty() : true si la pile est vide• size() : nombre d'éléments dans la liste• front() : accès à la donnée en tête – consultation ou

modification• back() : fournit la valeur de l'élément en fin – consultation ou

modification• push(valeur) : ajout d'un élément dans la file• pop() : fournit la valeur de l'élément en tête, en le supprimant

antislashn.orgC vers C++ 261

Page 262: Passer du langage C au langage C++

STL – priority_queue

• Gestion de file d'attente FIFO– ajout des éléments toujours en fin, avec une certaine

priorité définie par une relation d'ordre défini sous formed'un prédicat

– construction uniquement sur deque

priority_queue<int, deque<int> > q1;

– méthodes• empty() : true si la pile est vide• size() : nombre d'éléments dans la liste• top() : accès à la donnée en tête – consultation ou modification• push(valeur) : ajout d'un élément dans la file• pop() : fournit la valeur de l'élément en tête, en le supprimant

antislashn.orgC vers C++ 262

priority_queue<int, deque<int> > q1;priority_queue<int, deque<int>, greater<int> > q2;

Page 263: Passer du langage C au langage C++

STL – conteneurs associatifs

• Permet de retrouver une information par une clé et nonplus par sa position– l'élément est formé d'une clé et d'une valeur

• map impose l'unicité de la clé, multimap ne l'impose pas– l'opérateur [] sera permis sur le map, pas sur le multimap

• Deux autres conteneurs correspondent à des cas• Deux autres conteneurs correspondent à des casparticuliers de map et multimap– dans le cas ou la valeur associée à la clé n'existe pas

• les éléments se limitent à une seule clé

– set et multiset permettent de représenter des ensembles ausens mathématique

• présence d'une relation d'ordre appropriée

• le multiset permet la présence de plusieurs éléments identiques

antislashn.orgC vers C++ 263

Page 264: Passer du langage C au langage C++

STL - pair

• Patron de classe pair– permet de regrouper dans un objet deux valeurs

• Construction– à deux arguments

– affectation

pair <int, float> p (2, 1.3);

– affectation

– fonction make_pair

– membres publiques first et second

• La classe pair dispose des opérateurs == et <

antislashn.orgC vers C++ 264

p = pair<int, float>(8,6.3);

p = make_pair(7, 6.3f);

p.first=7; p.second=6.3;

Page 265: Passer du langage C au langage C++

STL - map

• Les éléments d'un map sont formés de deuxparties

– une clé et une valeur

• Permet d'accéder rapidement à la valeur associéeà la cléà la clé

– par l'opérateur []

– complexité en C(Log n)

• Patron de classe pair

– permet de regrouper dans un objet deux valeur

antislashn.orgC vers C++ 265

Page 266: Passer du langage C au langage C++

STL - map

• Construction d'un map

– par utilisation de la relation d'ordre par défaut (<)

• construction d'un conteneur vide

• construction par recopie d'un conteneur de même type

map<char, Point> m1;

• construction par recopie d'un conteneur de même type

• construction à partir d'une séquence

antislashn.orgC vers C++ 266

map<char, Point> m2(m1);

list< pair<char, Point> > lr(…);map<char, Point> m (lr.begin(),lr.end());

Page 267: Passer du langage C au langage C++

STL - map

• Construction d'un map

– choix de l'ordre

• on impose au conteneur une relation autre que l'ordrenaturel sous forme d'un prédicat binaire prédéfini (commeless ou greater)less ou greater)

• la fonction membre key_comp() fournit la fonction utiliséepour ordonner les clés

antislashn.orgC vers C++ 267

map<char, Point, greater<char> > m1;

Page 268: Passer du langage C au langage C++

STL - map

• Accès aux éléments– par l'opérateur []

• si une clé n'existe pas, elle est créée

map<char, int> m;m['S'] = 3;… = m['a'];

la paire ('S',3) est créée si la clén'existe pas, sinon la valeur de l'élémentest modifié

– accès par itérateur• on peut accéder aux éléments de la paire par les propriétés

publiques first et second

– recherche par la méthode find(clé) qui fournit unitérateur sur l'élément ayant une clé donnée

antislashn.orgC vers C++ 268

… = m['a'];

si la clé 'a' n'existe pas, création d'unepaire ('a',0)

(*it).first;

Page 269: Passer du langage C au langage C++

STL - map

• Insertions

– la méthode insert permet

• l'insertion d'une valeur donnée– insert(paire)

• les éléments d'un intervalle• les éléments d'un intervalle– insert(debut_sequence,fin_sequence)

• à une position donnée– insert(position,paire)

» la position est une suggestion faite pour facilité la recherche

antislashn.orgC vers C++ 269

Page 270: Passer du langage C au langage C++

STL - map

• Suppressions– la méthode erase permet

• la suppression à une position donnée– erase(position)

• les éléments d'un intervalle– erase(debut_sequence,fin_sequence)– erase(debut_sequence,fin_sequence)

• l'élément d'une clé donnée– erase(clé)

– la méthode clear() vide le conteneur

• Gestion mémoire– les opérations sur les map n'entrainent jamais

d'invalidation des références et des itérateurs

antislashn.orgC vers C++ 270

Page 271: Passer du langage C au langage C++

STL - multimap

• Une même clé peut apparaitre plusieurs fois– pas d'opérateur []– find(clé) fournit un itérateur sur un des éléments ayant la clé

recherchée• pas nécessairement le premier, il faut utiliser la fonction lower_bound

– erase(clé) supprime plusieurs éléments– permet de connaitre le nombre d'élément ayant– count(clé) permet de connaitre le nombre d'élément ayant

une clé donnée– informations sur l'intervalle d'éléments ayant une clé

équivalente• lower_bound(clé) : itérateur sur le 1er élément• upper_bound(clé) : itérateur sur le dernier élément• equal_range(clé) : fournit une paire des valeurs constituée des

deux itérateurs précédents

antislashn.orgC vers C++ 271

Page 272: Passer du langage C au langage C++

STL – set multiset

• set est un cas particulier du map

– aucune valeur n'est associée à la clé

– un élément d'un set est une constante, on ne peutpas le modifier

• est un autorisant plusieurs clés• multiset est un set autorisant plusieurs cléséquivalentes

antislashn.orgC vers C++ 272

Page 273: Passer du langage C au langage C++

STL – algorithmes standards

• Les algorithmes standards se présentent sous laforme de patrons de fonction

– le code n'a pas la connaissance précise des élémentsqu'il devra manipuler

• la manipulation des éléments passent par les itérateurs• la manipulation des éléments passent par les itérateurs

antislashn.orgC vers C++ 273

Page 274: Passer du langage C au langage C++

STL – algorithmes standards

• Les différentes catégories d'itérateur– nous avons rencontrés les itérateurs unidirectionnels,

bidirectionnels et à accès direct– il existe deux autres types d'itérateurs

• en entrée• en sortie• en sortie

– on peut hiérarchiser les itérateurs

antislashn.orgC vers C++ 274

itérateur en entrée itérateur en sortie

itérateur unidirectionnel

itérateur bidirectionnel

itérateur à accès direct

Page 275: Passer du langage C au langage C++

STL – algorithmes standards

• itérateur en entrée (in)– opérations possibles

• affectation : it1 = it2

• incrémentation : it++ ou ++it

• lecture : a = *it– impossible de faire *it = a

– impossible de faire– impossible de faire a = *it; b = *it;

• test d'égalité : it1 == it2

– comme un itérateur unidirectionnel, mais ne permet pasde modifier la valeur correspondante

– n'autorise qu'un seul passage sur les éléments de lacollection

• type d'itérateur utilisé pour la lecture de flux– il n'est pas possible de lire deux fois une même valeur sur certains flux,

comme l'entrée standard

antislashn.orgC vers C++ 275

Page 276: Passer du langage C au langage C++

STL – algorithmes standards

• itérateur en sortie (out)– opérations possibles

• affectation : it1 = it2

• incrémentation : it++ ou ++it

• écriture : *it = a– impossible de faire a = *it– impossible de faire *it = a; *it = b;– impossible de faire *it = a; *it = b;

– comme un itérateur unidirectionnel, mais ne permet pasde modifier la valeur correspondante

– n'autorise qu'un seul passage sur les éléments de lacollection

• type d'itérateur utilisé pour l'écriture sur un flux– il n'est pas possible d'écrire deux fois une même valeur au même

endroit, comme sur la sortie standard

antislashn.orgC vers C++ 276

Page 277: Passer du langage C au langage C++

STL – algorithmes standards

• Itérateur unidirectionnel (for pour forward)– permet de balayer du début à la fin

• sans retour en arrière

– les opérations sur les itérateurs in et out sont disponibles surcet itérateur

• partout où un itérateur in ou out est requis, peut être remplacé par unitérateur foritérateur for

• Itérateur bidirectionnel (bi)– comme for avec en plus it-- et --it

• Itérateur à accès direct (ran)– comme bi avec en plus

• opérateur [] : it[3];• arithmétique sur les itérateurs : it+=3;• offre les mêmes fonctionnalités qu'un pointeur conventionnel

antislashn.orgC vers C++ 277

Page 278: Passer du langage C au langage C++

STL – algorithmes standards

• Algorithmes et séquences

– de nombreux algorithmes s'appliquent sur uneséquence définie par un intervalle d'itérateurs

• les arguments sont classiquement les début et fin deséquenceséquence

– certains algos s'appliquent à deux séquences demême taille

• recopie par exemple

• les arguments à passer sont alors– deux arguments de début et fin pour la première séquence

– un troisième argument pour le début de la seconde séquence

antislashn.orgC vers C++ 278

Page 279: Passer du langage C au langage C++

STL – algorithmes standards

• Itérateur d'insertion– de nombreux algos doivent modifier les valeurs d'une

séquence

– patron de classe insert_iterator

insert_iterator <list<int> > ins;

• pour affecter une valeur à cet itérateur on utilise le patron defonction inserter

– c est le conteneur

– it est l'itérateur où se fera l'insertion

– il existe trois fonctions pour la valeur initiale de l'insertion» inserter(conteneur, position)

» front_inserter(conteneur)

» back_inserter(conteneur)

antislashn.orgC vers C++ 279

ins = inserter(c, it);

Page 280: Passer du langage C au langage C++

STL – algorithmes standards

• Itérateurs de flux

– itérateur de flux de sortie

• patron ostream_iterator

• exemple sur la sortie standardostream_iterator<char> flcar(cout);

– itérateur de flux d'entrée

• patron istream_iterator

• exemple sur l'entrée standard

antislashn.orgC vers C++ 280

ostream_iterator<char> flcar(cout);*flcar = 'a';

istream_iterator<int> flint(cin);int i = *flint;

Page 281: Passer du langage C au langage C++

STL – algorithmes standards

• Algorithmes d'initialisation d'intervalles

– copie d'une séquence• copy(debut_sequence,fin_sequence,iterateur);

– copie à partir de debut_sequence vers iterateur

– les éléments doivent être de même typeles éléments doivent être de même type

• copie inverse avec copy_backward

– génération de valeurs• generate(debut_sequence,fin_sequence,fonction);

– ou la fonction fonction génère les valeurs

• voir aussi generate_n, et fill

antislashn.orgC vers C++ 281

Page 282: Passer du langage C au langage C++

STL – algorithmes standards

• Algorithmes de recherche– recherche de valeur

• la valeur est imposée

• les algos sont basés sur l'égalité ==, ou un prédicat unairefournit sous forme de fonction

: recherche une valeur– find : recherche une valeur

– find_first : recherche une valeur parmi plusieurs

– search_n : recherche une valeur répétée n fois

– adjacent_find : recherche les doublons adjacents

– recherche d'extremum• max_element et min_element

– utilisent <, ou une relation donnée sous forme de prédicat binaire

antislashn.orgC vers C++ 282

Page 283: Passer du langage C au langage C++

STL – algorithmes standards

• Algorithmes de transformation

– remplacements de valeurs• replace(debut_seq,fin_seq,old_val,new_val);

– remplace toutes les old_val par new_val dans la séquence

• replace_if(debut_seq,fin_seq,condition,new_val);

– remplace toutes valeurs satisfaisant à une condition

• famille des fonctions en xxx_copy qui réalise le mêmetraitement que xxx sans modifier la séquence d'origine eten copiant dans une autre séquence

– replace_copy, reverse_copy

antislashn.orgC vers C++ 283

Page 284: Passer du langage C au langage C++

STL – algorithmes standards

• Algorithmes de transformation

– permutations de valeurs

• rotate : permutation circulaire d'une séquence

• génération de permutation en changeant l'ordre de la listeordonnéeordonnée

– next_permutation et prev_permutation

• random_shuffle : permutation aléatoire des valeurs de laséquence

antislashn.orgC vers C++ 284

Page 285: Passer du langage C au langage C++

STL – algorithmes standards

• Algorithmes de suppression

– remove(debut, fin, val) : supprime tous leséléments d'une valeur val donnée

• utilise l'opérateur ==

• voir aussi remove_if qui se base sur un prédicat unaire• voir aussi remove_if qui se base sur un prédicat unaire

– unique(debut,fin) : ne conserve que la premièrevaleur d'une série de valeurs égales

– renvoie un itérateur sur la fin du remaniement de lacollection

antislashn.orgC vers C++ 285

Page 286: Passer du langage C au langage C++

STL – algorithmes standards

• Algorithmes de tri

– la plupart de ces algorithmes nécessites des itérateursà accès direct

– le tri est effectué par l'opérateur < ou par un prédicatbinairebinaire

– on peut réaliser des tris complets, ou sur uneséquence particulière

• sort, partial_sort

antislashn.orgC vers C++ 286

Page 287: Passer du langage C au langage C++

STL – algorithmes standards

• Algorithmes de recherche et fusion

– s'appliquent sur des séquences ordonnées

– algos de recherche dichotomique (binaire)• binary_search

– lower_bound et upper_bound fournissent les première et– lower_bound et upper_bound fournissent les première etdernière positions possibles

– algos de fusion

• fusionne deux séquences ordonnées pour les réunir dansune troisième

– merge fusionne deux séquences en une troisième

– implace_merge fusionne deux séquences en une seul

antislashn.orgC vers C++ 287

Page 288: Passer du langage C au langage C++

STL – algorithmes standards

• Algorithmes à caractère numérique

– algos qui effectuent des opérations fondées sur lesopérateurs numériques : +, - , *

• accumulate : somme des éléments d'une séquence

• inner_product : produit scalaire de deux séquences de• inner_product : produit scalaire de deux séquences demême taille

• partial_sum : crée une nouvelle séquence formée descumuls partiels d'une première séquence

• adjacent_difference : crée une séquence formée de ladifférence de deux éléments consécutifs

antislashn.orgC vers C++ 288

Page 289: Passer du langage C au langage C++

STL – algorithmes standards

• Algorithmes à caractère ensembliste– permet de faire des unions, intersection, différences

sur les ensembles• se fondent sur l'opérateur == ou un prédicat binaire

– set_union, set_intersection, set_difference

• Algorithmes de manipulation de tas• Algorithmes de manipulation de tas– algos bas niveaux

– la notion de tas est fondée sur celle d'arbre binaire• make_heap permet de réarranger une séquence sous forme

de tas

• pop_heap, push_heap, sort_heap permettent lamanipulation du tas

antislashn.orgC vers C++ 289

Page 290: Passer du langage C au langage C++

C++11 - tuple

• Collection de taille fixe d'objets de typesdifférents

– include <tuple>

• Fonctions membres

– constructeur, operator=, swap

• Fonctions tiers

– make_tuple, get, opérateurs de comparaison, …

antislashn.orgC vers C++ 290

Page 291: Passer du langage C au langage C++

Google Protocol Buffers

• Protocol Buffers (noté PB) permet la sauvegarde dedonnées structurées sous forme textuelle et binaire– texte : lisible

– binaire : compacte et simple à traiter en programmation

– c'est une alternative à XML– c'est une alternative à XML

• PB est multi-langage, multiplateforme– mis au point par Google pour ses propres besoins

– spécification d'un protocole de sérialisation

– porté en C++, Java et Python

– site de référence :http://code.google.com/intl/fr/apis/protocolbuffers/docs/overview.html

antislashn.orgC vers C++ 291

Page 292: Passer du langage C au langage C++

Google Protocol Buffers

• Une donnée structurée est simple à traiter si elleest sous forme d'objet en mémoire, et persistéedans un fichier.

– principe de la sérialisation sur fichier

• Google fournit un compilateur qui à partir d'un• Google fournit un compilateur qui à partir d'undocument (le proto) génère la classe.

– cette classe comporte les méthode de sérialisation etdésérialisation vers le fichier

antislashn.orgC vers C++ 292

Page 293: Passer du langage C au langage C++

Google Protocol Buffers

• Étapes de développement

1. définition de la structure proto

2. compilation par le compilateur de la classe

• cette classe est dérivée d'une classe Message

3. écriture de l'application qui utilise la classe générée3. écriture de l'application qui utilise la classe générée

4. compilation habituelle

• lien avec la librairie protobuf

5. l'état de l'instance peut être sérialisé dans un fichier.proto

antislashn.orgC vers C++ 293

Page 294: Passer du langage C au langage C++

Google Protocol Buffers

• Téléchargement des archives– http://code.google.com/p/protobuf/downloads/list

– deux archives• compilateur• librairies

• Récupérer le projet VSProjects et lancer la compilationen mode Release– en mode Release

• Lancer les tests– exécutables qui ont étés créés lors de la compilation du projet

• Lancer l'utilitaire extract_includes.bat• Copier les fichiers *.lib générés• le fichier readme.txt livré avec le projet explique le

déroulement de la compilation

antislashn.orgC vers C++ 294

Page 295: Passer du langage C au langage C++

Google Protocol Buffers

• Création d'un fichier proto minimaliste

– fichier Hello.protomessage Hello{required string data =1 [default="Hello, world"];}

– le champ data de type string est obligatoire

• peut-être required ou optional

– le numéro d'ordre (=1) du champ

– la valeur par défaut

• optionnel

antislashn.orgC vers C++ 295

Page 296: Passer du langage C au langage C++

Google Protocol Buffers

• Compilation du fichier Hello.proto

• Ce qui génère les fichiers

protoc --cpp_out=. Hello.proto

espacedeux tirets

• Ce qui génère les fichiers

– Hello.pb.cc et Hello.pb.h

– Dans le fichier .h apparait les méthodes pour notrepropriété data

• has_data(), clear_data(),set_data(…), data()

• Faire un nouveau projet pour tester la classe

antislashn.orgC vers C++ 296

Page 297: Passer du langage C au langage C++

Google Protocol Buffers

• Présentation de l'API

– Méthodes héritées de Message

• IsInitialized() : vérifie si tous les champs sont initialisés

• DebugString() : renvoie le message sous forme de string

• CopyFrom(…) : met à jour le Message• CopyFrom(…) : met à jour le Message

– Sérialisation

• SerializeToString(…) : sérialise sous forme de chaine

• SerializeToOstream(…) : sérialisation binaire

• ParseFromString(…) : désérialise depuis une chaine

• ParseFromIstream(…) : désérialisation binaire

antislashn.orgC vers C++ 297

Page 298: Passer du langage C au langage C++

Bibliographie

• Le langage et la bibliothèque C++ - Norme ISO

– Henri Garreta - Ellipses

• Passeport pour C++ - Concepts et mise enpratique

– Georges Hansel – Vuibert

• Effective C++ - 55 Specific ways to improve yourprograms

– Scott Meyers

antislashn.orgC vers C++ 298

Page 299: Passer du langage C au langage C++

Web

• site de Bjarne Stroustrup• http://www2.research.att.com/~bs/homepage.html

• C++ Faq-lite• http://jlecomte.ifrance.com/c++/c++-faq-lite/index-fr.html

• Code de grande personne• http://h-deb.clg.qc.ca/Sujets/

• Google :• Google :– Google C++ Style Guide

• http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Nested_Classes

– Sérialisation• http://code.google.com/intl/fr/apis/protocolbuffers/docs/overview.html

• Qt– Designing Qt-Qtyle C++ APIs

• http://doc.trolltech.com/qq/qq13-apis.html

antislashn.orgC vers C++ 299

Page 300: Passer du langage C au langage C++

Copyleft

Support de formation créé par

Franck SIMON

http://www.franck-simon.com

antislashn.orgC vers C++ 300

Page 301: Passer du langage C au langage C++

Copyleft

Cette œuvre est mise à disposition sous licence Attribution

Pas d'Utilisation Commerciale

Partage dans les Mêmes Conditions 3.0 France.

Pour voir une copie de cette licence, visitezhttp://creativecommons.org/licenses/by-nc-sa/3.0/fr/http://creativecommons.org/licenses/by-nc-sa/3.0/fr/

ou écrivez à

Creative Commons, 444 Castro Street, Suite 900, Mountain

View, California, 94041, USA.

antislashn.orgC vers C++ 301