78
Cours C++ (2002) semaine 2 jour 4

Cours de C++, en français, 2002 - Cours 2.4

Embed Size (px)

Citation preview

Page 1: Cours de C++, en français, 2002 - Cours 2.4

Cours C++ (2002)

semaine 2

jour 4

Page 2: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 2

Plan du jour

Utilisation des exceptions

Niveaux de rattrapage

Programmation défensive

Debugging

Page 3: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 3

Rappel de l’historique de C++

C++ date du début des années 80 : ajout de

la notion de classe

1990 : ajout des notions de templates et

d’exceptions

1993 : ajout de la notion de namespace

Processus de normalisation entre 1995 et

1997

Normalisation ANSI/ISO en 1998

Page 4: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 4

Vu dans le cours

Nous avons vu déjà quelques caractéristiques de C++ :

Les classes, le minimum pour un langage orienté objet !

Les templates, qui rajoutent les possibilités de la programmation générique

Les namespaces, qui suppriment l’espace d’adressage unique de C

La STL, qui est partie intégrante du standard ANSI/ISO C++ (msvcrt.dll ?)

Page 5: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 5

Pas encore vu dans le cours

Il nous reste à voir

L’héritage multiple dans les classes : un cas

spécial de l’héritage que nous avons déjà vu

L’héritage multiple : demain

Les exceptions et leur gestion

Mise en place d’exceptions en C++

Utilisation dans la programmation

Page 6: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 6

Exceptions

C est un langage qui peut être sale très

rapidement

Comme C est inclus dans C++, la même

remarque est valable pour C++

Des erreurs sur des pointeurs se traduisent

généralement par des terminaisons de

programmes assez « abruptes »

Page 7: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 7

Exceptions (2)

Sur Unix, une erreur grave dans un

programme se traduit par l’apparition d’un

core dump de taille parfois importante

Sur Windows, une erreur grave se traduit

par un blue screen

Sur Windows XP, une sorte de core dump est

généré pour être envoyé au site Microsoft

Les développeurs de Microsoft ont-ils regardé

dans les sources de Linux ????

Page 8: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 8

Exceptions (3)

En C, il existait déjà trois méthodes

permettant de faire de la gestion d’erreurs

errno et perror() : petit mécanisme pour la

génération et le traitement de numéros d’erreurs

signal() et raise() : utilisent les signaux du

système, malheureusement disponibles en

nombre limité

setjump() et longjump() qui permettent de faire

des core dump soit même et de les réutiliser

Page 9: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 9

Exceptions (4)

C++ offre des mécanismes de gestion d’exceptions

Le terme de gestion d’exception est bien meilleur que celui de gestion d’erreur

C’est pourtant la même chose !

Les exceptions doivent être vu comme l’équivalent des messages envoyés entre objets même il s’agit ici de messages particuliers signalant les problèmes

Page 10: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 10

Exceptions (5)

La gestion des exceptions se fait de manière

périphérique

Le code normal reste (presque) le même

Le code de gestion des exceptions est fourni en

complément du code normal

Il est bon de ne pas ignorer les erreurs, elles

finissent toujours par arriver

Il est bon de prévoir au moins un cas de

traitement par défaut

Page 11: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 11

Exceptions (6)

La gestion des exceptions se fait à l’aide de

trois mots clé distincts

try : on essaie d’exécuter une suite

d’instructions mais une exception pourrait s’y

produire

catch : on récupère une exception pour la traiter

throw : on envoie une exception, c’est à dire

que l’on crée une condition d’erreur

Page 12: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 12

Exceptions (7)

Un throw peut envoyer n’importe quoi

Il peut envoyer des types de base, comme les

int

Il peut envoyer des classes qui auront été

préalablement définies par le programmeur

Un throw qui est envoyé dans la nature

signalera à l’environnement qu’une erreur

grave est arrivée

Page 13: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 13

Exceptions (8)

#include <iostream>

#include <string>

using namespace std;

void f_throw_int()

{

int i = 0;

throw i;

}

void main()

{

f_throw_int();

}

Page 14: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 14

Exceptions (9)

Si vous compilez et exécutez le programme

précédent, l’exception envoyée avec le throw

arrivera directement dans le système

d’exploitation !

Acceptez toutes les étapes pour rentrer dans le

debugger, puis fermez le (vous pouvez même

sauver le core avant)

En sortant du debugger, vous retrouver une fenêtre

« normale » de terminaison du programme

Page 15: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 15

Exceptions (10)

Le throw a en fait

Créé un objet (et appelé son constructeur !)

Envoyé cet objet comme résultat de la fonction

même si celle-ci est déclarée void (!)

De manière osée, il est possible de

considéré ce mécanisme comme un

alternatif au mécanisme normal de retour de

valeur !

Page 16: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 16

Exceptions (11)#include <iostream>

#include <string>

#include <cstdlib>

using namespace std;

class RuntimeError

{

string message;

public:

RuntimeError();

RuntimeError( string s );

void printMessage();

};

RuntimeError::RuntimeError()

{

message = "A runtimeError occured";

}

Page 17: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 17

Exceptions (12)RuntimeError::RuntimeError( string s )

{

message = s;

}

void RuntimeError::printMessage()

{

cout << message << endl;

cerr << message << endl;

}

void f_throw_int()

Page 18: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 18

Exceptions (13)

Note :

Certains langages orientés objet mettent à la

disposition du programmeur un énorme

ensemble de classes prédéfinies indiquant une

exception

Java en offre énormément !

Ce n’est pas le cas de C++ où le nombre

d’exceptions prédéfinies est réduit

Page 19: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 19

Exceptions (14)

Note (suite)

Certains langages font également la distinction

entre

Une erreur : cas le plus grave qui nécessite

généralement l’arrêt du programme

Une exception : pour les cas moins graves, où il est

encore possible de continuer le traitement après une

phase de « nettoyage »

Page 20: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 20

Exceptions (15)

Envoyer une exception ne suffit pas, encore

faut-il savoir quoi en faire et où

Le try marque un bloc où des exceptions

peuvent se produirent

La fin d’un bloc de try est constitué de blocs

de catch qui permettent de traiter les

exceptions

Les catch sont des message handlers !

Page 21: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 21

Exceptions (16)

void main()

{

try

{

f_throw_int();

}

catch( int ie )

{

cout << "catch an integer exception : " << ie << endl;

}

}

Page 22: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 22

Exceptions (17)

void f_throw_rt_filled()

{

throw RuntimeError( "a RuntimeError message" );

}

void main()

{

try {

f_throw_rt_filled();

}

catch( int ie ) {

cout << "catch an integer exception : " << ie << endl;

}

catch( RuntimeError re ) {

cout << "catch a runtime error : ";

re.printMessage();

}

}

Page 23: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 23

Exceptions (18)

En compilant et en exécutant le code, vous

obtenez deux fois le message

La console sert à la fois pour cout et pour cerr,

la sortie caractères standard pour les erreurs

Vous pouvez supprimer la ligne cerr dans la

méthode printMessage de RuntimeErrror

Page 24: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 24

Exceptions (19)

Dans le code précédent, plusieurs clauses

catch sont données les unes à la suite des

autres

Il est possible de faire plusieurs message

handler en un seul endroit !

La liste est traitée à la manière d’un switch

mais il n’est pas besoin de mettre un break car

un seul exception handler sera exécuté de toutes

façons

Page 25: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 25

Exceptions (20)

Pour être propre avec la définition des

fonctions, il est bon de signaler qu’une

fonction est capable d’envoyer une

exception

void f_throw_int() throw( int )

void f_throw_rt_void() throw( RuntimeError )

void f_throw_rt_filled() throw()

throw() = peut envoyer des exceptions dont on ne

connaît pas la nature

Page 26: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 26

Exceptions (21)

Cependant la spécification du throw est optionnelle

La meilleure preuve en est que nous n’avons pas eu de problèmes à la compilation jusqu’à présent…

Ceci est dû au fait que des fonctions C++ peuvent faire appel à des fonctions C ou C++ développées avant la mise en place des exceptions et qui pourraient donc en renvoyer sans en être consciente !

Page 27: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 27

Exceptions (22)

Pour conserver la similitude avec le switch, il est important de signaler que C++ vous offre la possibilité de traiter des exceptions qui n’apparaissent pas dans le liste des catch

Un peu à la manière du default dans un switch

Le cas est noté catch( … )

Ce cas particulier peut même être mis seul

C’est compact mais cela n’apporte aucun renseignement !

Page 28: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 28

Exceptions (23)

void main()

{

try {

f_throw_rt_filled();

}

catch( int ie ) {

cout << "catch an integer exception : " << ie << endl;

}

// catch( RuntimeError re ) {

// cout << "catch a runtime error : ";

// re.printMessage();

// }

catch( ... ) {

cout << "catch an exception" << endl;

}

}

Page 29: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 29

Exceptions (24)

Dans le cas où l’on ne met pas de catch(…),

il est possible de rattraper les erreurs juste

avant le passage sous debugger

Fonction unexpected()

Le système possède une fonction

unexpected() mais il est possible de définir

sa propre fonction, avec un nom différent

set_unexpected( pointeur_sur_fonction )

Page 30: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 30

Exceptions (25)

#include <exception>

void my_unexpected() {

cout << “Houston? We’ve got a problem here!" << endl;

exit( 0 );

}

void main() {

set_unexpected( my_unexpected );

try {

f_throw_rt_filled();

}

catch( int ie ) {

cout << "catch an integer exception : " << ie << endl;

}

//catch( RuntimeError re ) {…}

//catch( ... ) {…}

}

Page 31: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 31

Exceptions (26)

Il existe une autre fonction pour prendre en

compte les exceptions non prévues qui se

révèle utile

set_unexpected() ne marche pas correctement

sur Windows !

La fonction est set_terminate

Elle est utilisée de manière un peu différente

Page 32: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 32

Exceptions (27)…

void my_unexpected() {

cout << "something happened !" << endl;

exit( 0 );

}

void (*old_terminate)() = set_terminate( my_unexpected );

void main() {

// set_unexpected( my_unexpected );

try {

f_throw_rt_filled();

}

catch( int ie ) {

cout << "catch an integer exception : " << ie << endl;

}

//catch( RuntimeError re ) {…}

//catch( ... ) {…}

}

Page 33: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 33

Exceptions (28)

Amusement avec les exceptions :

Un catch est fait pour traiter une exception

reçue dans le bloc de try

Normalement, un catch traite l’exception

Un catch peut cependant renvoyer l’exception

qu’il est censé traiter : d’autres catch la traitront

à nouveau :catch( type identifiant )

{

// traitemnent

throw // on renvoie l’exception à nouveau

}

Page 34: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 34

Exceptions (29)

Les exceptions standardisées C++ font

partie de la STL

exception : la classe mère de toutes les autres

logic_error : sous-classe d’exception, marque

une erreur de logique du programme

runtime_error : sous-classe d’exception,

marque une erreur rencontrée à l’exécution

Page 35: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 35

Exceptions (30)

Les sous-classes de logic_error :

domain_error : violation d’une précondition

invalid_argument

length_error

out_of_range

bad_cast

bad_typeid

Page 36: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 36

Exceptions (31)

Les sous-classes de runtime_error :

range_error : violation d’une post-condition

overflow_error

bad_alloc : mémoire, mémoire…

Page 37: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 37

Exceptions (32)…

void f_throw_std_ex()

{

throw exception( “The STL exception message" );

}

void main()

{

try

{

f_throw_std_ex();

}

catch( exception e )

{

cout << "catch an stl exception : " << e.what() << endl;

}

}

Page 38: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 38

Exceptions (33)

Quand ne pas utiliser les exceptions :

Les exceptions ne sont pas faites pour vérifier

des conditions d’erreurs standards, préférer un

if pour vérifier qu’on ne divise pas par 0 !

Les exceptions ne sont pas non plus faites pour

effectuer un enchaînement d’opérations en

remplacement du flot normal de C et C++

Il existe d’autre moyens de vérifier des

conditions !

Page 39: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 39

Exceptions (34)

Quand utiliser les exceptions :

Il est possible de régler le problème (paramètres) et de réappeler la fonction qui a causé l’exception

Permet de calculer un résultat alternatif par défaut à celui qui devait être fourni par la fonction

Permet de faire ce que l’on peut et de renvoyer une exception au niveau au dessus

La même exception ou une autre

Page 40: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 40

Exceptions (35)

Quand utiliser les exceptions (suite) :

Permet de contrôler les appels et les résultats de

fonctions appelées dans une vieille librairie C et

d’éviter certains problèmes

Simplifie l’écriture et la lecture du programme

Les programmes et librairies sont plus sûrs

À court terme, facilite le debugging

À long terme, améliore la robustesse

Page 41: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 41

Exceptions (36)

Quand utiliser les exceptions (suite) :

Dans les constructeurs, pour signaler les

problèmes d’initialisation (la mémoire par

exemple)

Attention pas dans les destructeurs car on n’est

jamais sûr du résultat dans ce cas : les pointeurs

n’ont pas de destructeurs en C++ !

Page 42: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 42

Programmation défensive

La programmation défensive part de l’idée

qu’il est possible de vérifier certaines

choses avant de commencer une exécution

Il est également possible d’en vérifier après

la fin de l’exécution

Ceci correspond à la mise en place de

préconditions et de post-conditions

Page 43: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 43

Programmation défensive (2)

Nous avons déjà parlé de ces conditions pour OCL, l’Object Constraint Language de l’UML

Il s’agit là d’un rajout inspiré par une théorie du génie logiciel, le Design By Contract de Bertrand Meyer

Le Design By Contract est une théorie

Un langage orienté objet repose sur cette théorie

Page 44: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 44

Programmation défensive (3)

Idée du Design By Contract :

« Si tu promets d’appeler la méthode m en

respectant la précondition alors, en retour, la

méthode m promet de respecter la

postcondition »

Il faut donc normalement faire des

vérifications avant l’appel d’une fonction

pour que le résultat retourné soit juste

Page 45: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 45

Programmation défensive (4)

Il est possible de retourner le problème et de

considérer que la fonction effectuera le

traitement après avoir vérifier que les

paramètres fournis respectent certaines

conditions, avant d’effectuer le traitement et

de finalement vérifier, avant le return, que

les conditions définies pour le résultat sont

respectées

Page 46: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 46

Programmation défensive (5)

Un langage de programmation orienté objet

permet d’effectuer de telles manipulations

très simplement pusique les préconditions et

postconditions sont au cœur du langage :

Eiffel, langage développé par … Bertrand

Meyer

Page 47: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 47

Programmation défensive (6)

Il est possible de définir des conditions en

C++ (en fait, même en C)

Ces conditions peuvent servir

indifféremment

Au début d’une fonction, avant l’exécution

proprement dite

Pendant l’exécution de la fonction et

À la fin ou après l’exécution de la fonction

(mais toujours dans le même bloc)

Page 48: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 48

Programmation défensive (7)#include <iostream>

using namespace std;

class Date {

int an;

int mois;

int jour;

public:

Date();

Date( int j, int m, int a );

void print();

};

Date::Date()

{

an = 1;

mois = 1;

jour = 1;

}

Page 49: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 49

Programmation défensive (8)Date::Date( int j, int m, int a )

{

an = a;

mois = m;

jour = j;

}

void Date::print()

{

cout << "jour " << jour;

cout << ", mois " << mois;

cout << ", an " << an << endl;

}

Page 50: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 50

Programmation défensive (9)void main()

{

Date d1 = Date();

d1.print();

Date d2 = Date( 45, 33, 10191 );

d2.print();

}

Après l’exécution de ce petit programme, il est clair

qu’il manque des choses.

Il est possible de rajouter des tests mais que faire si les

conditions sont fausses ? Envoyer une exception ?

Page 51: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 51

Programmation défensive (10)

Il est tout d’abord possible d’équiper le

code avec une série d’appels à la fonction

assert

Elle réalise le test fourni et vérifie qu’il est

satisfait

S’il n’est pas satisfait, une sorte d’exception est

lancée et il devient alors possible de passer sous

debugger

Page 52: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 52

Programmation défensive (11)#include <cassert>

Date::Date( int j, int m, int a )

{

assert( j >= 1 && j <= 31 );

assert( m >= 1 && m <= 12 );

assert( a >= 1971 && a <= 2050 );

an = a;

mois = m;

jour = j;

}

Page 53: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 53

Programmation défensive (12)

Quel est l’intérêt de l’assert ?

L’assert n’est en fait utilisable que lors de la

phase de développement, qui est également une

phase où l’on se retrouve fréquemment sous

debugger

Sans modifier le code en aucune manière, il est

possible de supprimer l’apparition de ces

pseudo exceptions causées par l’assert

Page 54: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 54

Page 55: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 55

Page 56: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 56

Page 57: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 57

Page 58: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 58

Programmation défensive (17)

Si vous réexécutez ce même programme, aucune

erreur n’apparaît bien que les conditions

mentionnées dans l’assert ne soit pas respectées

L’assert est donc uniquement utilisée lorsque la

compilation et l’édition de lien sont placés en mode

debug

L’assert va finalement beaucoup moins loin que le

Design By Contract, qui fonctionne également

lorsque le programme n’est plus en debug (tel que

dans Eiffel) !

Page 59: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 59

Programmation défensive (18)

Il est possible de considérer la fonction

assert comme une aide aux tests à grande

échelle (en grande quantité) tels que ceux

préconisés dans la méthodologie XP

Cependant, ces tests sont beaucoup moins

efficaces que l’utilisation d’un langage

formel tel que l’OCL

C’est un bon début, mais insuffisant !

Page 60: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 60

Debug sous Visual Studio

Visual Studio offre des possibilités de debugging

assez similaires aux autres IDE

Si vous en connaissez un, vous les connaîtrez tous !

Il est possible de définir des breakpoints

Il est possible de faire des step over, step into et

step out

Il est possible de faire de l’évaluation de variables

en cours d’exécution et de les ajouter à une liste de

variables observées (add watch)

Page 61: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 61

Debug sous Visual Studio (2)#include <iostream>

#include <string>

using namespace std;

class Test

{

string message;

public:

Test();

Test( string s );

void print();

};

Test::Test() {

message = "A default Test message";

}

Test::Test( string s ) {

message = s;

}

Page 62: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 62

Debug sous Visual Studio (3)void Test::print()

{

cout << message << endl;

}

void f_void()

{

string msg = "message local de f_void";

msg += " !";

cout << msg << endl;

}

int f_int( int ii )

{

int i = 2;

return ( ( ( ( i * i ) * i ) * i ) + ii );

}

Page 63: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 63

Debug sous Visual Studio (4)void main()

{

Test test = Test( "un test" );

Test* pTest = new Test();

int i = 0;

f_void();

cout << f_int( 1 ) << endl;

}

Page 64: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 64

Page 65: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 65

Page 66: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 66

Page 67: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 67

Page 68: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 68

Page 69: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 69

Page 70: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 70

Page 71: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 71

Page 72: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 72

RTTI

La mise en place des exceptions en C++ a

nécessité une certaine harmonisation des

fonctions permettant d’obtenir des

informations sur les classes

Entre autre, l’identification du type à

l’exécution a été harmonisée

Il vous est donc possible de récupérer des

informations RTTI dans vos programmes, pour

le debug ou les assert

Page 73: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 73

RTTI (2)

Il existe donc une classe, typeid, qui permet

de découvrir les informations sur les types

de toute variable

Marche pour les types de base

Marche, bien sûr, pour les classes

Cette classe possède plusieurs méthodes

dont une intéressante pour nous :

name()

Page 74: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 74

RTTI (3)#include <iostream>

#include <string>

#include <cassert>

using namespace std;

class Test

int f_int( int ii ) { … }

class U { public: virtual ~U(); };

void main()

{

int i = 0;

Test t = Test();

void* pt = new Test();

assert( typeid( 47 ) == typeid( i ) );

assert( typeid( &i ) == typeid( int* ) );

cout << typeid( t ).name() << endl;

Page 75: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 75

RTTI (4)

cout << typeid( t.print() ).name() << endl;

cout << typeid( f_int( i ) ).name() << endl;

cout << typeid( pt ).name() << endl;

// ca ne marche pas à tous les coups !

//cout << typeid( (*pt) ).name() << endl;

U* pu = 0;

try

{

typeid( *pu );

}

catch( bad_typeid )

{

cout << "typeid s'est plante" << endl;

}

}

Page 76: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 76

RTTI (5)

Il faut normalement compiler avec l’option /GR qui active complètement le RTTI utilisé par typeid (par défaut /GR- : désactivé)

Mais voilà, avec Microsoft, cela ne suffit pas !

L’exception bad_typeid qui devait être envoyée (en théorie dans toute implémentation du C++ standard) ne l’a pas été…

Page 77: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 77

RTTI (6)void main()

{

U* pu = 0;

try

{

typeid( *pu );

}

catch( bad_typeid )

{

cout << "typeid s'est plante" << endl;

}

catch( ... )

{

cout << "pseudo bad_typeid recu" << endl;

}

}

Page 78: Cours de C++, en français, 2002 - Cours 2.4

Cours semaine 2 jour 4 Cours C++ 78

Questions / Remarques