Vous êtes sur la page 1sur 26

CHAPITRE 22

Exercices

Ce chapitre prsente un certain nombre dexercices dont les corrigs sont donns sur un support lectronique spar1 . Les exercices sont groups par souschapitre, et la numrotation suit la numrotation des chapitres. Les numros des exercices correspondent aux numros des solutions. Ces exercices ont t compils avec diffrents compilateurs. La mention du ou des compilateurs nest pas systmatique. Il se peut que certains de ces exercices compils avec une certaine version dun compilateur puissent provoquer des erreurs sur certains autres. Il en va en particulier ainsi des exercices ralisables en C ANSI plutt quexclusivement en C++. La compatibilit ANSI des compilateurs C++ est ingale, et souvent soumise au choix dune ou plusieurs options pas toujours claires au premier abord. Lensemble des exercices corrigs a t ralis en utilisant lditeur fourni avec le CD, soit Editeur V3.4. Il sagit dun logiciel shareware, donc sujet des droits dutilisation. Ces droits doivent tre pays lauteur, M. J.-P Menicucci, et se montent environ 100 FF (vrifier le montant exact mentionn dans le formulaire denregistrement fourni dans laide du programme). Les coordonnes de lauteur peuvent tre trouves ladresse indique sur la figure suivante. On peut aussi consulter le site (http://www.studioware.com) afin de vrifier sil nexiste pas une version plus rcente de ce logiciel. Le paiement des finances denregistrement vous donne accs toutes les nouvelles versions de Editeur. Il est bien sr possible aussi dutiliser votre propre environnement de dveloppement, au cas o vous auriez fait lacquisition dun autre systme. Il est possible dans ce dernier cas de figure que certains caractres (minuscules accentues, par exemple) ne soient pas supportes par votre environnement de dveloppement. Lditeur supporte plusieurs formats de fichier, ainsi que trois langues de
1. Les corrigs des exercices font partie du CD de distribution du cours C++ ainsi que lditeur et le systme de dveloppement permettant la rsolution de ces exercices.

Le langage C++

337

einev

Tlcommunications

mjn

dialogue (Franais, anglais, italien). Il supporte galement ldition de macros, ce qui en fait un outil trs efficace pour lutilisateur averti. Sa simplicit dutilisation en font un outil utilisable galement par les novices. Enfin, la possibilit d utiliser divers langages de programmation en font aussi un accessoire utile pour dautres langages, comme Java, par exemple.

Le compilateur utilis est galement livr avec le CD : il sagit dun portage par Cygnus Solutions du compilateur de GNU pour Windows 32. Il est ncessaire de disposer de Windows 95 ou Windows NT pour utiliser cet environnement. Hormis le compilateur, qui compile aussi bien du code C ANSI (gcc) que C++ ANSI (g++), lenvironnement fourni propose aussi divers utilitaires bien connus des utilisateurs de UNIX, comme make, flex, awk, etc... Les habitus de UNIX se trouveront leur aise avec cet environnement qui inclut galement le shell bash, alors que les habitus de Windows devront se raccoutumer un peu la manipulation de fentres alphanumriques. Cet exercice est de toutes faons ncessaire du fait que les exercices proposs utilisent intgralement des entres-sorties alphanumriques. Le compilateur GNU est gratuit, et se trouve galement sur les diverses moutures de UNIX, et bien sr sur Linux. Lutilisation de ces exercices corrigs dans un autre environnement que Windows requiert une adaptation de format des fichiers. Consulter le site de Cygnus (http://www.cygnus.com) afin de vrifier sil nexiste pas une nouvelle version : celle actuellement distribue sur le CD est la version B20. La difficult des exercices est trs variable. En principe, ils sont classs par ordre croissant de difficult, sauf si la logique demande un autre squencement (exercices lis la terminaison pralable dune autre exercice). La difficult de lexercice est signale par un code alphanumrique dans la donne. Ce code correspond aux indications de difficult frquemment rencontres pour la cotation ditinraires de montagne par lUIAA (Union Internationale des Alpinistes Amateurs); ceci ne signifie pas que les dangers inhrents la ralisation de lexercice soient la mesure du danger rencontr dans un itinraire de montagne correspondant ! Le plus grave danger auquel on sexpose dans ce genre dexercice est une ventuelle frustration : F : facile. Ralisable en quelques minutes. PD : peu difficile. Ralisable en une demi-heure.

338

Le langage C++

einev

Tlcommunications

mjn

AD : assez difficile. Il vaut mieux prvoir une petite heure. D : difficile. Un aprs-midi (4 heures) devrait nanmoins suffire. TD : trs difficile. Une journe (8 heures) sera bien remplie. ED : extrmement difficile. Il sagit dun projet de longue haleine, et le corrig nest pas

forcment fourni, parceque lauteur na peut-tre pas trouv de solution satisfaisante. XD : exceptionnellement difficile. Niveau travail de doctorat. Fourni sans corrig. Les temps indiqus peuvent varier pour certains exercices. En ralit, certains exercices de niveau facile contiennent un nombre lev de points traiter, ce qui peut effectivement prendre pas mal de temps. Les corrigs, quand ils existent, sont regroups par dossiers. Chaque sous-chapitre de cette liste dexercices a un dossier correspondant localis lintrieur du dossier Exercices corrigs. Le nom du dossier contenant les corrigs est mentionn dans len-tte des donnes dexercices, et les fichiers respectifs sont indiqus dans la donne.

Le langage C++

339

einev

Tlcommunications

mjn

22.4

Une rapide introduction C++

1. 2. 3.

4.

Les corrigs se trouvent dans le dossier Exercices corrigs/Hello. (F) Ecrire un programme qui crit Hello sur la console en utilisant <stdio.h> (F) Ecrire un programme qui crit Hello sur la console en utilisant <iostream.h>. (F) Ecrire un programme qui permet de lire un entier et un caractre du clavier en utilisant <stdio.h>. (F) Ecrire un programme qui permet de lire un entier et un caractre du clavier en utilisant <iostream.h>

340

Le langage C++

einev

Tlcommunications

mjn

22.5

Le prprocesseur
Les corrigs se trouvent dans le dossier Exercices corrigs/Le prprocesseur.

1.

2.

(F) Ecrire un programme affichant systmatiquement le numro de la ligne quil est en train dexcuter (Corrig : LineNo.c). (F) Ecrire un programme utilisant soit stdio.h soit iostream.h selon quil est compil par un compilateur C ou un compilateur C++.

Le langage C++

341

einev

Tlcommunications

mjn

22.6

Types de base et drivs

Tous ces exercices ne sont pas solubles sans un petit regard en avant sur les fonctions. Les notions introduites dans le paragraphe dfinissant C++ en un clin doeil devraient pourtant tre suffisantes. Les corrigs se trouvent dans le rpertoire Types. 1. (F) Ecrire une macro dfinissant le type Byte. (Un byte est un mot de huit bit, dont le MSB (Most Significant Bit) reprsente le signe). On suppose que la machine cible utilise un jeu de caractres de type USASCII. 2. (PD) Dfinir une structure implmentant des variables VeryLongInt (entiers sur 256 bit). 3. (PD) Afficher sur lcran une variable de type VeryLongInt. 4. (AD) Lire depuis le clavier une valeur de type VeryLongInt. 5. (F) Dfinir un type VeryLongInt. 6. (PD) Utiliser le code dfini en (exercice 3, page342) et (exercice4, page342) en lincluant la structure dfinissant le type VeryLongInt.

342

Le langage C++

einev

Tlcommunications

mjn

22.7

Types standard introduits par C++

Le langage C++

343

einev

Tlcommunications

mjn

22.8

Oprateurs standard et instructions

Avant daborder ces exercices, il est ncessaire dtudier galement le chapitre consacr aux instructions. Pour faire le moindre exercice ayant un intrt quelconque, il faut avoir une connaissance au moins lmentaire des oprateurs de base et des instructions du langage. Les corrigs de ces exercices peuvent tre consults dans le dossier Exercices corrigs/Oprateurs standard. 1. (PD) Ecrire un programme permettant lentre dun nombre entier depuis le clavier, et laffichage de : Son carr Sa factorielle Les bits le composant (prendre garde la taille de lentier pouvant varier selon les implmentations) Sa parit Sil sagit dun carr parfait, et si oui, afficher la racine. Sil sagit dun nombre premier Le programme bouclera sur lui-mme tant quon ne lui a pas donn la valeur 0 traiter. La sortie du programme ralis ressemblera peu prs la squence suivante (Metrowerks Code Warrior avec des entiers de 2 byte) :
Entrer un entier 13 Carre de 13 : 169 La factorielle de 13 est -13312 Representation binaire de 13: 000001101 13 est un nombre impair 13 n'est pas un carre parfait 13 est un nombre premier Entrer un entier 5 Carre de 5 : 25 La factorielle de 5 est 120 Representation binaire de 5: 000000101 5 est un nombre impair 5 n'est pas un carre parfait 5 est un nombre premier Entrer un entier 16 Carre de 16 : 256 La factorielle de 16 est -32768 Representation binaire de 16: 000010000 16 est un nombre pair 16 est un carre parfait, dont la racine vaut 4 16 n'est pas premier, puisque divisible par 2 Entrer un entier

344

Le langage C++

einev

Tlcommunications

mjn

Au plaisir de vous revoir ...

Corrig : BasicOps.cpp.
2.

(PD) Ecrire un programme permettant lintroduction dun rel et dun entier au clavier, et affichant le rel lev la puissance entire. Chercher optimiser lalgorithme en minimisant le nombre de multiplications relles. Le programme bouclera sur lui-mme tant quon ne lui a pas donn la valeur 0 comme puissance entire traiter. Corrig : Power.cpp.

Le langage C++

345

einev

Tlcommunications

mjn

22.9

Instructions

Les exercices spcifiques aux instructions (chapitre 9) sont regroups avec les exercices spcifiques aux oprateurs standard ( Voir Oprateurs standard et instructions, page 344.), ces deux thmes tant indissolublement lis lorsque lon veut crire ne serait-ce que le plus lmentaire des programmes.

346

Le langage C++

einev

Tlcommunications

mjn

22.10

Fonctions

Les exercices portant sur lutilisation de fonctions sont implmenter sous forme de modules spars, comme il est dusage en C. La fonction fait lobjet dun fichier de dfinition (X.h) importable (#include) par un autre programme, et dun fichier implmentation (X.C, X.cp, X.cpp) compil sparment, et li au programme appelant par lditeur de liens (linker), sous forme de code objet. Les corrigs de ces exercices se trouvent dans le dossier Exercices corrigs/Fonctions 1. (F) Reprendre lexercice exercice1, page344 sur les oprateurs standard, et convertir la srie doprations implmente en une srie dappels de fonctions. Les fonctions seront implmentes dans un module de compilation spar, dot dun fichier interface. 2. (PD) Ecrire une fonction calculant le nombre de Fibonacci dun nombre pass en paramtre. Rappelons que le nombre de Fibonacci F(n) est dfini comme suit : F(0) = 1; F(1) = 1; F(n) = F(n - 1) + F(n-2) Comparer une solution rcursive et une solution non rcursive; critiquer le rsultat. Peuton en tirer des conclusions gnrales ? Corrig : Fibonacci/fibo.cpp
3.

4.

5.

(PD) Ecrire une fonction implmentant le tri de valeurs entires. Cette fonction devra tre appelable aussi bien avec un tableau constant quun tableau non constant. La mthode de tri utilise (quicksort, bubble, insertion, etc...) est laisse au libre choix de limplmentateur. Corrig : Quicksort/main.cpp (PD) Ecrire une fonction calculant le plus grand diviseur commun (PGCD) de deux nombres entiers. Corrig : Pgcd/Pgcd.cpp (AD) Dans un systme de tlcommunications, on peut estimer les pertes dans un rseau de connexion en utilisant la relation dErlang :

A--- --N! Cette relation a lallure suivante : B = ----------------N i A ----i!

i=0

A est le trafic, et mesure le degr doccupation des sources. Cest le produit du taux de sollicitation de ces sources par la dure doccupation par les serveurs. Ainsi, si il vient en moyenne un client par heure un guichet, et que le guichetier met en moyenne 10 minutes pour traiter le client, ce guichetier va traiter un trafic de 1/6 Erlang. N est le nombre de serveurs (ou le nombre de guichetiers, si lon prfre)

Le langage C++

347

einev

Tlcommunications

mjn

B est la probabilit pour une sollicitation de ne pas trouver de serveur (probabilit de pertes). Complexe valuer, cette relation se prte bien au calcul par ordinateur. On dsire fixer son calcul dans un module de librairie, dont on pourra importer le code au besoin. Ecrire une fonction importable par un programme quelconque permettant lvaluation de la probabilit de pertes selon Erlang, puis crire un programme de test utilisant cette fonction. La sortie du programme de test ressemblera peu prs la sortie suivante :
Entrer le trafic 10 Entrer le nombre de serveurs devant traiter 10 Erlang 20 Probabilite de pertes pour un trafic de 10 Erlang sur 20 serveurs B = 0.186913 % Entrer le trafic 100 Entrer le nombre de serveurs devant traiter 100 Erlang 150 Probabilite de pertes pour un trafic de 100 Erlang sur 150 serveurs B = 6.51117e-05 % Entrer le trafic 0

Trafic nul ou negatif, bye, bye ...

6.

7.

On cherchera raliser un programme capable de calculer cette relation pour un grand nom bre de serveurs (ordre de grandeur 10000) Corrig : Erlang/Erlang.cpp (D) Liste gnrique. Implmenter une srie de fonctions permettant le contrle dune liste chane (linked list). Cette liste permettra de stocker nimporte quel type de donnes, mais sera homogne (tous les lments de la liste stockent des donnes identiques). Les possibilits offertes par cette liste seront : Cration dune liste Destruction dune liste Parcours de la liste avec appel dune fonction dfinie par lutilisateur pour chacun des lments de la liste Insertion une position dtermine de la liste Destruction dun lment Ajout dun lment en queue de liste On veillera dans cette implmentation ce que le code crit puisse implmenter plusieurs listes diffrentes simultanment. En dautres termes, il est prfrable dviter les donnes statiques dans le module dimplmentation. (AD) Liste gnrique (suite). Est-il possible dtendre la liste de lexercice6, page348 une liste inhomogne (cest--dire contenant des donnes pas forcment de mme type) ? Si cest possible, est-ce judicieux ?
Le langage C++

348

einev

Tlcommunications

mjn

Le langage C++

349

einev

Tlcommunications

mjn

22.11

Oprateurs

Il sagit ici plus particulirement des oprateurs spcifiques C++, ainsi que de constructions plus volues du langage C. En particulier, on dcouvrira dans ces exercices, quelques exercices plus spcifiquement dvolus aux piges que peuvent receler les pointeurs, et la manire dutiliser des rfrences pour accrotre la scurit dun programme. Les corrigs se trouvent dans le classeur Exercices corrigs/Oprateurs. (AD) Soit le type suivant :

1.

typedef struct { double real; double imag; } Complex;

2.

3.

Dfinir les oprateurs +, - , / et * pour le type Complex et les intgrer dans un module de compilation spar du programme de test, avec un fichier de dfinition de prototypes (.h). Le corrig de cet exercice ainsi que du suivant se trouve dans le dossier Complex :complex.cp / complex.h. (F) Pour lexercice prcdent, on dsire disposer dun oprateur << agissant sur un ostream, et dun oprateur >> agissant sur un istream, de manire similaire aux oprateurs correspondant pour les types standard. (PD) Ecrire un petit programme crant dynamiquement un tableau dentiers en mmoire, de dimensions spcifies lors de lexcution, par une entre de lutilisateur. Initialiser le tableau ainsi cre laide de la fonction de librairie rand() (Utiliser laide en ligne du systme de dveloppement pour localiser rand()). Utiliser ensuite la fonction de tri dveloppe lors de l exercice3, page347 pour trier ces valeurs. Avant la terminaison du programme, veiller librer la place occupe par le tableau.

350

Le langage C++

einev

Tlcommunications

mjn

22.12

Classes

1.

2.

3.

4.

Les corrigs de ces exercices se trouvent dans le classeur Exercices corrigs/Classes. (F) Reprendre et utiliser la classe Strings dfinie dans le cadre de ce chapitre avec un programme de test. (F) Utiliser la classe Point dfinie dans ce chapitre dans un programme principal. Le programme principal inclura le fichier Point.h, et lors de ldition de liens, utilisera le fichier rsultant de la compilation de Point.C. Le programme principal (main.C ) se contentera dinstancier quelques objets de type Point, et dafficher leur contenu. Corrig: Point:Point.cp (F) Ajouter la mthode move(float deltax, float deltay) la classe Point, et la tester. (AD) Soit la classe suivante :

#include <iostream.h> class X { int i; public : void setI(int k) { i = k;} int getI() { cout<<i<<endl; return i; } };

i peut-il tre modifi directement par un programme principal instanciant la classe X ? Vrifier l'existence et le fonctionnement du constructeur par dfaut. Vrifier l'existence et le fonctionnement du constructeur de copie. Ecrire un constructeur de manire interdire un utilisateur l'instanciation de cette classe

sans valeur initiale. Utiliser le code du constructeur pour ajuster i la bonne valeur. Modifier la classe X de manire ce que le membre priv i soit une rfrence, et non plus une valeur, comme dans :
class X { int& i;// Rfrence, et non plus valeur ! public : ..... };

Comment modifier les membres publics de la classe pour que le programme compile et

fonctionne? Pourquoi? Ecrire un constructeur de copie, et s'assurer que le constructeur de copie gener jusque l par le compilateur n'est plus utilis. 5. (AD) Convertir le module dvelopp au cours de lexercice 1, page350 implmentant des oprations sur des nombres complexes, en une classe Complex. 6. (D) Tableau de dimensions variables. Sous C (et C++), les tableaux sont implments par la syntaxe suivante :
<type> <dnomination_du_tableau>[<dimension>];

Exemple :

Le langage C++

351

einev

Tlcommunications

mjn

int

tableauEntier[200];

dclare un tableau de 200 entiers. Cette implmentation souffre des limitations et des inconvnients suivants : L'indication de dimension ne fait pas partie du tableau. Lors du passage d'un tableau comme paramtre une procdure, il est ncessaire de passer la dimension du tableau de manire spare la procdure invoque (ou pire, de stocker cette information dans une variable accessible globalement). La dimension du tableau est fixe. Il n'est pas possible de faire varier la taille d'un tableau en fonction de ses besoins, si bien qu'une application doit soit dclarer systmatiquement des dimensions maximales (comment les estimer ?), soit utiliser des pointeurs avec les risques que l'on peut imaginer. La syntaxe utilise pour dtruire (delete []) un tableau dclar l'aide de pointeurs est diffrente de celle utilise pour dtruire un lment simple (delete), ce qui augmente le risque d'erreurs. Du fait que les dimensions du tableau sont fixes, il n'est pas possible d'optimiser la place mmoire occupe. La borne infrieure du tableau est toujours 0. Il n'est pas possible de dclarer, de manire analogue PASCAL, par exemple, un tableau sous la forme ARRAY[-5..12] OF integer ; On ne peut pas copier un tableau dans un autre sans utiliser une boucle itrative fastidieuse, inversment des langages comme PASCAL ou MODULA-2. Un tableau n'offre pas de scurit d'accs. Toute tentative d'indexer (par indexation ou l'aide d'un pointeur) un lment inexistant est, au mieux, dtecte par une violation de la protection mmoire, quand cette dernire existe (c'est heureusement le cas sous UNIX). Au pire, on accde d'autres variables places proximit du tableau, ce qui promet un diagnostic de pannes assez ardu. Dans le mme ordre d'ides, la possibilit d'accder aux lments d'un tableau l'aide de pointeurs augmente le risque d'accs illicites l'aide de pointeurs non correctement initialiss. On ne peut pas simplement crire un tableau dans un flot d'entres-sorties.

On se propose de dvelopper un type tableau liminant tout ou partie des inconvnients cits i-dessus. Pour simplifier, dans un premier temps, nous ne considrons que le type tableau d'entiers. Nous nous rserverons une ventuelle gnralisation pour des exercices futurs. A chacun d'crire son propre cahier des charges du tableau qu'il dsire implmenter, en tant entendu qu'il devra l'implmenter lors des exercices. La liste d'inconvnients i-dessus n'est pas exhaustive, et certains de ces inconvnients peuvent ne pas tre ressentis comme tels par un implmentateur donn. Libre donc chacun de dfinir le tableau qui lui parat le mieux correspondre ses dsirs d'utilisateur. Le corrig se trouve dans le dossier IntArray:IntArray.cp. 7. (D) Smaphores et mmoire partage sous UNIX

352

Le langage C++

einev

Tlcommunications

mjn

8.

On se propose d'encapsuler le mcanisme de smaphores de UNIX, ainsi que les mcanismes de mmoire partage, dans une classe C++. Ces mcanismes comprennent les queues de messages (Message queues), les smaphores (Semaphores), et les zones mmoire partages (Shared Memory). Le corrig se trouve dans le dossier IPC:MSGQ.C / IPC:MSGQ.H et IPC:SMC.C / IPC:SMC.H. (D) Liste gnrique. Mettre les fonctions dveloppes lors de lexercice6, page348, sous forme de classe.

Le langage C++

353

einev

Tlcommunications

mjn

22.13

Classes imbriques

354

Le langage C++

einev

Tlcommunications

mjn

22.14

Hritage

1.

(AD) Soit les deux classes suivantes :

class A { protected : int i; public : A(int k) : i(k) { cout<<"A constructed "<<i<<"\n"; } ~A() { cout<<"A deleted\n"; } }; class B : public A { private : int j; public : B(int k, n = 1) : A(k), j(n) { cout<<"B constructed "<<j<<"\n"; } ~B() { cout<<"B deleted\n"; } };

Que gnre le programme suivant ?


main() { A a(1); B b(2); }

Vrifier sur les machines et commenter. Que gnre le programme suivant ?


int main(char**, int) { A *a, *b; a = new A(10); b = new B(20, 30); delete a; delete b; return 0; }

Vrifier sur les machines et commenter. Est-ce correct ? Si non, localiser et corriger l'erreur Dfinir, pour les deux classes, la mthode print() qui imprime la valeur des membres privs ou protgs. Pour les deux classes, cette fonction doit avoir la mme signature. Dfinir une procdure printA(*A) [ void printA(A *theArgument) ] dont l'argument est un *A, et qui invoque simplement la mthode print() de theArgument. Que gnre le programme suivant :
int main(char**, int) { A *a, *b; a = new A(10); b = new B(20,30); printA(a); printA(b);

Le langage C++

355

einev

Tlcommunications

mjn

delete a; delete b; return 0; }

Vrifier sur les machines et commenter. Que faudrait-il pour que la mthode print de B imprime galement la valeur de A ? Soit le programme suivant :
int main(char**, int) { A *a, *b; a = new A(10); b = new B(20, 30); B b1(*b); delete a; delete b; return 0; }

Commenter le rsultat. Peut-on faire en sorte que ce programme fonctionne correctement ? Pour le programme prcdent, remplacer la construction par copie de b par une copie de a, de manire semblable B b2(*a); en ayant tenu compte des constatations faites lors de la question prcdente. Que se passe-t-il ? Commenter le rsultat. Dfinir une classe C qui contient un objet de classe B comme membre priv, et tracer galement la construction/destruction. Comment se comporte l'instanciation de la classe C ? Vrifier le comportement du constructeur de copie gnr automatiquement pour A, B et C. 2. (F) Quand faut-il imprativement dclarer un destructeur comme virtuel ? Peut-on mettre une rgle gnralement applicable ? 3. (D) Implmenter une hirarchie d'objets graphiques, parmi lesquels on introduira le point, la droite, l'ellipse, le cercle, le rectangle, le carr, un polygone quelconque, etc.... Les surfaces peuvent tre remplies, les traits peuvent avoir diverses paisseurs. Pour viter le recours un systme de dessin (Macintosh, Windows ou X), on implmentera les mthodes de dessin par de simples messages sur un terminal (Exemple : je suis un carr de ct XX centr en YY). Le programme de test devra tre en mesure de gnrer dynamiquement des objets graphiques sur demande de lutilisateur et les "dessiner" sur le terminal.

356

Le langage C++

einev

Tlcommunications

mjn

22.15

Hritage multiple

Soit la classe de base suivante :


class X { int i; public : X() { cout<<"Default constructor"<<endl; } X(int x) : i(x) { cout<<"X Constructed "<<i<<endl; } virtual ~X() { cout<<"X (~X) Destructed "<<i<<endl; } virtual void print() { cout<<"print X called "<<i<<endl; } };

Soit les classes derives suivantes :


class A : public X { int i; public : A(int k) : i(k) { cout<<"A Constructed "<<i<<endl; } virtual ~A() { cout<<"A (~A) Destructed "<<i<<endl; } virtual void print() { cout<<"print A called "<<i<<endl; X::print(); } }; class B : public X { int j; public : B(int n) : j(n) { cout<<"B Constructed "<<n<<endl; } virtual ~B() { cout<<"B (~B) Destructed "<<j<<endl; } virtual void print() { cout<<"print B called "<<j<<endl; X::print(); } }; class C : public A, public B { int j; public : C(int k, int a, int b, int x) : A(a), B(b), X(x), j(k) { cout<<"C Constructed "<<j<<endl; } virtual ~C() { cout<<"C (~C) Destructed "<<j<<endl; } virtual void print() {

Le langage C++

357

einev

Tlcommunications

mjn

cout<<"print C called "<<j<<endl; B::print(); A::print(); } };

puis le programme principal suivant :


main() { cout<<"Constructor"<<endl; C cc(100, 200, 300, 123456); cc.print(); }

Quel est le problme ? Comment le corriger ? Soit la procdure


1.

void

aProc(C anInstance) { anInstance.print(); }

2.

3.

que se passe-t-il si on appelle cette procdure depuis le programme principal? Peut-on contrler ce phnomne ? Crer une classe Motor et une classe Vehicle avec constructeurs et destructeurs, et une mthode print qui permette d'identifier les instances (par exemple avec un entier comme membre priv, ou une chane de caractres quelconque. Faire driver de ces deux classes la classe MotorVehicle (avec galement une mthode print) et observer le comportement lors de l'instanciation. Dfinir une procdure p prenant comme paramtre soit un pointeur sur un Motor ou sur un Vehicle, et lui passer un pointeur sur un MotorVehicle. Reprendre l'exercice prcdent, et dfinir la classe Engine, dont drivent la fois Motor et Vehicle. Modifier la dfiniton des classes en consquence, et modifier la procdure p pour qu'elle accepte comme paramtre un pointeur sur des Engine. Observer et commenter les comportements : a) dans le cas o Engine est une classe de base virtuelle (class Motor : virtual public Engine {} ... class Vehicle : virtual public Engine {}.. etc... ) b) dans le cas o Engine est une classe de base normale (class Motor : public Engine .. class Vehicle : public Engine {}..... etc... ) c) dans le cas o Engine est une classe de base normale et o la classe MotorVehicle n'implmente pas de mthode print() (class Motor : public Engine .. class Vehicle : public Engine {}..... etc... ). d) Comment appeler la mthode print d'un Vehicle ou d'un Motor faisant partie d'une instance de MotorVehicle?

358

Le langage C++

einev

Tlcommunications

mjn

22.16

Templates

1.

2.

3.

(PD) Implmenter la classe Array avec les mmes fonctionnalits que la classe dfinissant les tableaux dynamiques (paragraphe6, page351) pour des entiers, mais cette fois pour des types de donnes quelconques. (Voir aussi lexemple donn dans le cours). (AD) Implmenter une fonction template oprant le tri dun tableau (paragraphe3, page347) de valeurs de type quelconque. Quelles exigences poserez-vous au type de donnes trier ? (PD) Reprendre la classe Array dfinie en exemple dans ce chapitre (paragraphe 1, page359). Y ajouter une mthode sort() (paragraphe2, page359) permettant le tri du tableau, et un oprateur <<, permettant limpression du tableau sur un ostream. Ces mthodes additionnelles posent-elles des exigences particulires aux variables stockes dans le tableau? Lesquelles? Critiquer limplmentation.

Le langage C++

359

einev

Tlcommunications

mjn

22.17

Classes gnriques

1.

2.

3.

4.

5. 6.

7.

(AD) Dans le cadre d'un projet, il est ncessaire d'implmenter une file d'attente simple, de type FIFO (First In First Out), de longueur infinie, contenant des instances d'une classe A donne. Dfinir une classe gnrique permettant d'implmenter le modle gnral associ une file d'attente de ce type, puis en dduire une implmentation spcifique au problme de la classe A. (Note : il est judicieux de faire au pralable un effort de gnralisation) (AD) Plus tard, dans un autre projet, on dsire implmenter nouveau une file d'attente, mais de taille limite, en introduisant des priorits (certains membres peuvent tre traits en priorit). Les objets ne pouvant pas tre mis en file d'attente sont perdus, mais l'utilisateur de la file d'attente est averti de cette perte, de manire pouvoir entreprendre des mesures adquates en cas de dbordement. Montrer que le code du projet prcdent peut tre rutilis. (D) Dans un troisime projet, on dsirerait ajouter la file prcdente la notion de temps d'attente maximum limit, ainsi que des priorits variables (A chaque attente supplmentaire, la priorit augmente). Un lment qui excde son temps d'attente maximum est soit perdu, soit signifi l'utilisateur au moyen d'une fonction (callback function) qu'il dfinit lui-mme. Montrer que le code du projet prcdent peut tre rutilis. (D) Peut-on sans autre implmenter une file d'attente de type LIFO (Least In, First Out) partir du code gnr pour les prcdents projets? (Note : une file de type LIFO est, dans son expression la plus simple, identique une pile). (F) Implmenter le fichier typ dcrit dans le cadre du chapitre dcrivant les template. (D) Un fichier cyclique est un fichier qui se surcrit lorsqu'il atteint une taille dtermine. Implmenter un fichier cyclique l'aide d'une classe gnrique, et en driver un template pour l'utilisateur final. (D) Implmenter une classe gnrique implmentant le type fichier comprim, en utilisant une mthode de compression choix (par exemple Huffmann), et en driver un template pour lutilisateur final. Peut-on faire en sorte que lutilisateur puisse choisir parmi diverses mthodes de compression / dcompression, voire au besoin implmenter sa propre mthode ?

360

Le langage C++

einev

Tlcommunications

mjn

22.18

Exceptions

Les corrigs de ces exercices se trouvent dans le classeur Exercices corrigs:Exceptions.


1.

2.

(F) Sur la base du petit exemple prsent dans le cours, crire un exemple de traitement dexceptions bas sur la valeur dune variable globale. Corrig : except.cp. (F) Reprendre lexercice prcdent, et vrifier si le compilateur que vous utilisez traite correctement la destruction des objets en situation dexceptions. La rponse peut videmment varier dun compilateur lautre... Corrig : except.cp. Note : le corrig ne fournit pas la rponse, mais la manire de lobtenir...

Le langage C++

361

einev

Tlcommunications

mjn

362

Le langage C++

Vous aimerez peut-être aussi