Académique Documents
Professionnel Documents
Culture Documents
1Unproblmebienennuyeux
2Lagestiondesexceptions
3Lesexceptionsstandards
Unproblmebienennuyeux
Enprogrammation,quelquesoitlelangageutilis(etdoncenC++),ilexiste
plusieurstypesd'erreursquipeuventsurvenir.Parmileserreurspossibles,onconnat
djleserreursdesyntaxequisurviennentlorsquel'onfaitunefautedanslecode
source,parexemplesil'onoublieunpointvirgulelafind'uneligne.Ceserreurssont
facilementcorrigescarlecompilateurpeutlessignaler.
Unautretypedeproblmespeutsurvenirsileprogrammeestsyntaxiquement
correctmaisqu'ilexcuteuneactioninterdite.Onpeutcitercommeexemplelescaso
l'onessayedelirela10mecased'untableaude8lments,linsuffisancede
mmoire,l'ouvertured'unfichierinexistant(ouquinepeutpastrelupourunproblme
depermissions),ouencorelecalculdelaracinecarred'unnombrengatif.On
appelleceserreursleserreursd'implmentation.
Lerledunprogrammeconsisteprvoirceserreurs,eninformerlesutilisateurs
etventuellementmettreenuvredessolutionsderepriseetdecorrectiondeces
erreursdexcution.C++propose,partlutilisationdelavaleurderetourdes
fonctions,unenouvellesolutionpourintercepterleserreurs:lemcanismedes
438
exceptions.
Unproblmebienennuyeux
Lerledunprogrammeconsisteprvoirceserreurs,eninformerlesutilisateurs
etventuellementmettreenuvredessolutionsderepriseetdecorrectiondeces
erreursdexcution.C++propose,partlutilisationdelavaleurderetourdes
fonctions,unenouvellesolutionpourintercepterleserreurs:lemcanismedes
exceptions.
Exple:
intdivision(inta,intb)
{
returna/b;
}
intmain(){
inta,b;
cout<<"Valeurpoura:";
cin>>a;
cout<<"Valeurpourb:";
cin>>b;
cout<<a<<"/"<<b<<"="<<division(a,b)<<endl;
return0;
}
439
Unproblmebienennuyeux
Sionlanceleprogrammeavecb=0,onobtientuneerreur:
Valeurpoura:3
Valeurpourb:0
Exceptionenpointflottant(coredumped)
Ilfaudraitdoncnepasraliserlecalculsibvaut0:uncasexceptionneld'erreur
(uneexception),maisquefairelaplace?
440
Quelquesmauvaisessolutions:
Unepremirepossibilitseraitderenvoyerunnombreprdfinilaplacedu
rsultat:
intdivision(inta,intb)//Calculeadivisparb.
{
if(b!=0)//Sibnevautpas0.
returna/b;
else//Sinon.
returnERREUR;
}
EnspcifiantunevaleurprcisepourERREUR.Maiscelaposeunnouveau
problme,quellevaleurchoisirpourERREUR?Onnepeutpasrenvoyerunnombre
puisquetouslesnombrespourraienttrerenvoysparlafonctiondansuncas
normal.Cen'estdoncpasunebonnesolution.
441
Quelquesmauvaisessolutions:
Uneautreidequel'onrencontresouvent,c'estd'afficherunmessaged'erreur:
intdivision(inta,intb)//Calculeadivisparb.
{
if(b!=0)//Sibnevautpas0.
returna/b;
else//Sinon.
cout<<"ERREUR:Divisionpar0!"<<endl;
}
Maiscelaposedeuxnouveauxproblmes,lafonctionnerenvoieaucunevaleuren
casd'erreuretuneffetdebordseproduit;eneffetlafonctiondivisionn'estpas
forcmentcenseutilisercoutsurtoutsiparexemple,onaralisunprogramme
avecuneGUIcommeQtparexemple.
442
Quelquesmauvaisessolutions:
La3eetderniresolutionestdemodifierlasignatureetletypederetourdela
fonctiondelamaniresuivante:
booldivision(inta,intb,int&resultat){
bool
if(b!=0)//Sibestdiffrentde0.
{resultat=a/b;//Oneffectuelecalculetonmetlersultatdanslavariablepasse
//enargument.
returntrue;//Onrenvoievraipourmontrerquetouts'estbienpass.
}
elsereturnfalse;//Onrenvoiefalsepourmontrerqu'uneerreurs'estproduite.
}
Cettesolutionestlameilleuredes3proposes,maisellesouffred'ungros
problme,ellen'estpasdutoutintuitiveutiliser.Ilestenparticulierimpossiblede
raliserlecalculdemaniresimpleetintuitive.
Labonnesolutionestprsentedanslasuite:Lagestiondesexceptions.
443
Lagestiondesexceptions
Oncredeszonesol'ordinateurvaessayerlecodeensachantqu'uneerreurpeut
survenir.
Siuneerreursurvient,onlasignaleenlanantunobjetquicontientdesinformations
surl'erreur.
l'endroitol'onsouhaitegrerleserreurssurvenues,onattrapel'objetetongre
l'erreur.
Ces3motscorrespondentaux3motsclsquisontutilissparlemcanismedes
exceptions.
try{...}(essayeenfranais)permetdesignaleruneportiondecodeouneerreur
peutsurvenir.
throw(lanceenfranais)permetdesignalerl'erreurenlanantunobjet.
catch(...){...}(attrapeenfranais)permetd'introduirelaportiondecodequiva
rcuprerl'objetets'occuperdegrerl'erreur.
Onlanceunobjetenesprantqu'unautreboutdecodelerattrapera,sinonle
programmeplantera(labouteillelamer).
444
Les3motsclsendtail:
EnC++,lorsquilfautlanceruneexception,ondoitcrerunobjetdontlaclasse
caractrisecetteexception,etutiliserlemotclthrow.Sasyntaxeestlasuivante:
throwobjet;
oobjetestlobjetcorrespondantlexception.Onpeutlancern'importequoicomme
objet,parexempleunintquicorrespondaunumrodel'erreurouunestring
contenantletextedel'erreur.
throw123;//Onlancel'entier123,parexemplesil'erreur123estsurvenue.
throwstring("Erreurfatale.Contactezunadministrateur");//Onpeutlancerunestring.
throwPersonnage;//Onpeuttoutfaitlanceruneinstanced'uneclasse.
throw3.14*5.12;//Oummelersultatd'uncalcul
Uneinstructionthrowpeutsetrouvern'importeodanslecode,maiss'iln'estpas
dansunbloctry,l'erreurnepourrapastrerattrapeetleprogrammeplantera.
445
Les3motsclsendtail:
Lexceptiondoitalorstretraiteparlegestionnairedexceptioncorrespondant.On
nepeutattraperquelesexceptionsquisontapparuesdansunezonedecodelimite
(cettezoneestditeprotgecontreleserreursdexcution),passurtoutun
programme.Ondoitdoncplacerlecodesusceptibledelanceruneexceptiondun
blocdinstructionsparticulier.Ceblocestintroduitaveclemotcltry:
//Ducodesansrisque.
try
{
//Ducodequipourraitcreruneerreur.
}
Entrelesaccoladesdubloctryonpeuttrouvern'importequelleinstructionC++,
notammentunautrebloctry.
446
Les3motsclsendtail:
Lesgestionnairesdexceptionsdoiventsuivrelebloctry.Ilssontintroduitsavecle
motclcatch:
catch(classe[&][temp])
{
//Traitementdelexceptionassocielaclasse
}
Ilfautcrerunbloccatchpartyped'objetlanc.
Chaquebloctrydoitobligatoirementtresuivid'unbloccatch.Demanire
rciproque,toutbloccatchdoittreprcdd'unbloctryoud'unautrebloccatch.
Dansunbloccatchonpeutparexemple:
arrterleprogrammeavecousansmessageutilisateur;
corrigerleproblmeavecousansmessageutilisateur;
uniquementinformerlutilisateur.
447
Les3motsclsendtail:
try
{//Leblocsensibleauxerreurs.
}
catch(inte)//Onrattrapelesentierslancs
{//Ongrel'erreur.
}
catch(stringconst&e)//Onrattrapelesstringslancs.
{//Ongrel'erreur.
}
catch(Personnageconst&e)//Onrattrapelespersonnages.
{//Ongrel'erreur.
}
Vouspouvezmettreautantdeblocscatchquevousvoulez.Ilenfautaumoinsun
partyped'objetpouvanttrelanc.
448
Les3motsclsendtail:
1.catch(T):exceptiondutypeTainsiquecellesdesesclassesdrives.
2.catch(Tinfo):exceptiondutypeT,infoestunobjetdutypeT,utilispourextrairedes
informationssupplmentaires.
3.ilexisteungestionnaireparticulier,catch(...)quiattrapetouttyped'exception.Ce
gestionnairenepeutsetrouverqu'endernireposition(sinon,lesgestionnairesplacs
derrireluin'attraperaientjamaisrien).
intmain(){
try{
...
...
}
catch(constchar*s){/*...*/}
catch(intn){/*...*/}
catch(MonException&e){/*...*/}
catch(...){std::cerr<<"Exceptioninconnue";}
return0;
449
Labonnesolution1:
intdivision(inta,intb){
try//unthrowdoittoujourssetrouverdansunbloctry
{if(b==0)
throwstring("Divisionparzro!");//onlanceuneexception::unechane
else
returna/b;
}
catch(stringconst&chaine)
{
cerr<<chaine<<endl;//ongrel'exception::afficherunmessaged'erreur
}
}
Lafonctionpeutpotentiellementcriredanslaconsolealorsquecen'estpasson
rle.
Deplusleprogrammecontinue,alorsqu'uneerreurestsurvenue.
Lemieuxfaireseraitalorsdelancerl'exceptiondanslafonctionetdercuprer
450
l'erreur,sielleseproduit,danslemain.
Labonnesolution2:
intdivision(inta,intb){
if(b==0)
throwstring("ERREUR:Divisionparzro!");
else
returna/b;}
Vouspouvezremarquerquelethrownese
intmain(){
trouvepasdirectementl'intrieurdubloctry,
inta,b;
cout<<"Valeurpoura:";
maisqu'ilsetrouvel'intrieurd'unefonctionqui
cin>>a;
estappele,elle,dansunbloctry.
cout<<"Valeurpourb:";
cin>>b;
try{cout<<a<<"/"<<b<<"="<<division(a,b)<<endl;}
catch(stringconst&chaine){cerr<<chaine<<endl;}
}
Cettefois,leprogrammeneplanteplusetlafonctionn'aplusd'effetdebord.
C'estlameilleuresolution.Rsultat:Valeurpoura:3
Valeurpourb:0
451
ERREUR:Divisionparzro!
Qu'estcequeavachangerdurantl'excutionduprogramme?
l'excution,leprogrammevasedroulernormalementcommesilesinstructions
tryetlesblocscatchn'taientpasl.
Laleved'uneexceptions'apparenteunbranchement(goto).Lesinstructions
nonexcutes:
danslafonctionquialancl'exception,
danslesfonctionsrencontreslorsdelaremontedelapiled'appels,
danslebloctryquiacapturl'exception,
...sontabandonnes.
Lesvariableslocalescesfonctionssontdtruites(leursdestructeurssont
appels).Ilvachercherlebloccatchquicorrespondl'objetquiatlanc.
Arrivaubloccatch,ilvaexcutercequisetrouvedansleblocetreprendre
l'excutionduprogrammeaprslebloccatchetpasl'endroitosetrouvelethrow.
452
Exemple1:
encasderreur(lancementduneexception):
453
Exemple2:
siilnyapasderreur(pasdelancementdexception):
454
Rsum:
1.OncommenceparconstruireunobjetXdetypequelconquequireprsentera
l'erreur:dansl'exempleX,ilestdutypestring.
2.Onlanceuneexceptionsurcetobjetgrceaumotclrserv,throw.Pourcet
exemple,cetteexceptionestlancedanslecasolednominateurestnul.
3.Cetteexceptionestalorsenfermedansunbloctry,quipeutgnreruneerreur.
Nousavonsincluslafonctionquipeutgnreruneerreur,division(),danscebloctry.
4.Unbloccatchessaied'attraperl'objetX,reprsentantl'erreur.PuisqueXestdu
typestring,nousavonsdfiniuncatchdecetypel.
5.S'ilneparvientpas,unefonctionspciale(terminate)estappelepourterminer
l'excutionduprogramme.Parexemple,danslecasouncatchspcifiqueX
(doncunstring)n'apastdfini.Cen'estpaslecasdansnotreexemple.
455
Lesexceptionsstandards
Maintenantquel'onsaitgrerlesexceptions,laquestionprincipaleestdesavoir
queltyped'objetlancer.
Cetobjetpeuttredenimportequeltype:
typeprdfini:int(23),string("Divisionparzro!!");
typedfiniparl'utilisateur:classErreur{...};
typedrivd'untypestandard:classErreur:exception{...};
Ilestgalementpossibledelancerunobjetparexemplequicontiendraitplusieurs
attributscomme:
Unephrasedcrivantl'erreur.
Lenumrodel'erreur.
Leniveaudel'erreur(erreurfatale,erreurmineure...).
L'heurelaquellel'erreurestsurvenue.
Unbonmoyenderaliserceciestdedriverlaclasseexceptiondela
bibliothquestandardduC++.
456
Exempleavecuntypedfiniparl'utilisateur
#include<iostream>
#include<string>
#include<exception>
usingnamespacestd;
classexception_divzero{
stringmessage;
public:
exception_divzero():message("divisionparzro!"){}
stringget_message()const{returnmessage;}
};
inttest_denominateur(inta,intb){
if(b==0){
throwexception_divzero();
}
returna/b;//divisionentiere.
}
457
Exempleavecuntypedfiniparl'utilisateur
intmain(){
intc=0,a=1,b=0;
try{
c=test_denominateur(a,b);//divisionparzro!
cout<<"rsultat/division:"<<c<<endl;
}
catch(exception_divzeroe){
cout<<"Exceptionatcapture:"\
<<e.get_message()<<endl;
}
cout<<"suiteduprogramme!\n";
return0;
}
458
Laclasseexceptiondelalibrairiestandard
Laclasseexceptionestlaclassedebasedetouteslesexceptionslancesparla
bibliothquestandard.Elleestaussispcialementpensepourqu'onpuisseladriver
afinderalisernotrepropretyped'exception.Ladfinitiondecetteclasseest:
classexception
{
public:
exception()throw(){}//Constructeur.
virtual~exception()throw();//Destructeur.
virtualconstchar*what()constthrow();//Renvoieunechane"laC"contenant
//desinfossurl'erreur.
};
Pourl'utiliser,ilfautinclurelefichierd'enttecorrespondant,soiticilefichier
exception.
Lesmthodesdelaclassesontsuiviesdumotclthrow.Celasertindiquerque
cesmthodesnevontpaslancerd'exceptions...cequiestbienparcequelasila
classed'exceptioncommencelancerdesexceptions,onn'estpassortidel'auberge.
459
Solutionavecclassedrived'untypestandard
Onpeutalorscrersapropreclassed'exceptionenladrivantgrceunhritage:
#include<exception>
usingnamespacestd;
classErreur:publicexception{
public:
Erreur(intnumero=0,stringconst&phrase="",intniveau=0)throw()
:m_numero(numero),m_phrase(phrase),m_niveau(niveau){}
virtualconstchar*what()constthrow(){returnm_phrase.c_str();}
intgetNiveau()constthrow(){returnm_niveau;}
virtual~Erreur()throw(){}
private:
intm_numero;//Numrodel'erreur.
stringm_phrase;//Descriptiondel'erreur.
intm_niveau;//Niveaudel'erreur.
};
460
Solutionavecclassedrived'untypestandard
Onpourraitalorsrcrirenotrefonctiondedivisionde2entiersdelamaniresuivante
intdivision(inta,intb){
if(b==0)
throwErreur(1,"Divisionparzro",2);
else
returna/b;}
Cequidonnel'excution:
Valeurpoura:3
Valeurpourb:0
ERREUR:Divisionparzro
intmain(){
inta,b;
cout<<"Valeurpoura:";
cin>>a;
cout<<"Valeurpourb:";
cin>>b;
try{cout<<a<<"/"<<b<<"="<<division(a,b)<<endl;}
catch(std::exceptionconst&e){cerr<<"ERREUR:"<<e.what()<<endl;}
return0;
}
Unecopiedelobjetdexceptionestfaite:unconstructeurparcopiedelobjetdoit
existerpourlesclassesdexceptionsnontriviales
461
Quelestl'intrtdedriverlaclasseexception,alorsqu'onpourraitfairesa
propreclassesansaucunhritage?
Ilfautsavoirqu'onn'estpasleseullancerdesexceptions.Certainesfonctions
standardslancentellesaussidesexceptions.Touteslesexceptionslancesparles
fonctionsstandardsdriventdelaclasseexception,cequipermetavecuncode
gnriquederattrapertoutesleserreursquipourraientpotentiellementarriver.Cecode
gnriqueestlesuivant:
catch(std::exceptionconst&e)
{cerr<<"ERREUR:"<<e.what()<<endl;
}
Ceciestpossiblegrceaupolymorphisme.Onattrapeunobjetdetypeexception,
maisgrceauxfonctionsvirtuellesetlarfrence(lesdeuxingrdients!),c'estla
mthodewhat()delaclassefillequiseraappele,cequiestjustementcequel'on
souhaite.
Lesexceptionssontsymbolisespardesclassesdanslesquellesonpeutintgrer
lesnotionsd'hritageetdepolymorphisme.
462
Spcifierlesexceptions
Ilestpossibledespcifierlesexceptionsquunefonctionouunemthodeale
droitdelever:
classX{};
classA{
voidf1();//nimportequelletypeexception
voidf2()throw();//nepeutleverdexception
voidf3()throw(int);//peutleverdestypesint
voidf4()throw(int,double,X);//peutlever3typesdexceptions
};
voidg1();
voidg2()throw();
voidg3()throw(int);
voidg4()throw(int,double,X);
Durantlexcution,siuneexceptionduntypeinterditestleve,leprogramme
appelleunemthodespcialeunexpected()queleprogrammeurpeut
parailleursmodifieretutilisersaguise.
463
Exemple:
#include<iostream>
#include<string>
#include<exception>
usingnamespacestd;
voidf(inti)throw(string){///Uniquementdutypestring
inta=1;
if(!i)throwstring("Help!");///ok,carstring
//if(!i)throwa;///erreurcarint=>appeldeunexpected
cout<<"OK!\n";
}
catch(stringe){
intmain(){
cout<<"e:"<<e<<endl;
try{
}
f(0);
catch(int){
f(1);
cout<<"catch_int!\n";
}
}
return0;
}
464
Relanceruneexception:
Ilestpossiblederelanceruneexceptionreueparunbloccatchafindelaretraiter
unedeuximefoisplusloindanslecode.Pourcefaire,ilfaututiliserlemotclthrow
(i.e.sansargument).
catch(exceptionconst&e)//Rattrapetouteslesexceptions
{
//Ontraiteunepremirefoisl'exception
cerr<<"ERREUR:"<<e.what()<<endl;//traitementpartiel
throw;//Etonrelancel'exceptionreuepourlaretraiter
//dansunautrebloccatchplusloindanslecode.
}
465
Exemple:
#include<iostream>
#include<string>
#include<exception>
usingnamespacestd;
voidf(inti){
try{
throwi;
}
catch(inte){
if(e){
cout<<"catchin\n";
}else{
cout<<"e:"<<e<<endl;
}
throw;
}
cout<<"OK!\n";
intmain(){
try{
f(0);
f(1);
f(0);
f(1);
}
catch(stringx){
cout<<"catch_string!\n";
}
catch(int){
cout<<"catch_int!\n";
//throw;
}
cout<<"finduprogramme!\n";
return0;
}
466
Lesexceptionsstandards
Fichierentte<stdexcept>bibliothquestandardfournissantdesclasses
dexceptions
Plusieursexceptionsstandardsusceptiblesdtredclenchesparunefonction
ouunoprateurdelabibliothquestandard
467
Lesexceptionsstandards
Onpeutparexempleobserverunexempledebad_allocencasdchec
dallocationmmoireparnew
#include<iostream>
#include<vector>
Cequidonnelersultat:
ERREUR:std::bad_alloc
usingnamespacestd;
intmain()
{try
{vector<int>a(1000000000,1);//Untableaubientropgrand
}
catch(exceptionconst&e)//Onrattrapelesexceptionsstandardsdetoustypes.
{cerr<<"ERREUR:"<<e.what()<<endl;//Onafficheladescriptionde
l'erreur.
}
return0;
}
468
Exemple:
Examinonsmaintenantcommentonpourraitcreruntypecomplet,letype
TableauEntiers,quiutiliseraitleconceptd'exceptionsonavantage.
classTableauEntiers
{int*tab_;
inttaille_;
Quelssontlescas
d'exceptionpossibleslors
d'oprationssuruneinstance
deTableauEntiers?
public:
intGetTaille()const
{returntaille_;}
intoperator[](constintn)const
{returntab_[n];}
int&operator[](constintn)
{returntab_[n];}
TableauEntiers(constinttaille)
:tab_(0),taille_(taille)
{tab_=newint[GetTaille()];
}
~TableauEntiers()
{delete[]tab_;}
469
};
Exemple:
Unpremiercasidentifiableseraitceluio,lorsdel'appelduconstructeur,lataille
passeenparamtreseraitillgale(0oumoins).Onpourraitalorsdirequ'ils'agit
d'uneexceptiondetypeTailleInvalide.
Lamanirelapluslgantedegreruntelcasestdecreruneclasse
publiqueinternelaclasseTableauEntiers.
NousnommeronscetteclasseTailleInvalide(sonnomcompletestdonc
TableauEntiers::TailleInvalide).
Silatailleestinvalide,uneinstancedeTailleInvalideestcreetlance.
if(taille_<=0)throwTailleInvalide();
470
Exemple:
classTableauEntiers
{int*tab_;
inttaille_;
public:
classTailleInvalide{};
intGetTaille()const{returntaille_;}
intoperator[](constintn)const{returntab_[n];}
int&operator[](constintn){returntab_[n];}
TableauEntiers(constinttaille)throw(TailleInvalide)
:tab_(0),taille_(taille)
{
if(taille_<=0)throwTailleInvalide();
tab_=newint[GetTaille()];
}
~TableauEntiers()
{delete[]tab_;}
};
471
Exemple:
Unsecondcasidentifiableseraitceluio,pendantlaconstruction,lammoire
disponibles'avreinsuffisantepourobteniruntableaudelataillerclame.On
pourraitalorsdirequ'ils'agitd'uneexceptiondetypeMemoireInsuffisante.
Lestandardexprimedjceconceptl'aidedel'exceptionstandard
std::bad_alloc,quevoustrouverezdansl'enttestandard<new>.
#include<new>
usingstd::bad_alloc;
Plusieursexceptionsstandardsusceptilesd'etredclanchesparune
fonctionouunoprateurdelabibliothquestabdard
Exple.Bad_allocencasd'checd'allocationmmoireparnew
472
Exemple:
#include<new>
usingstd::bad_alloc;
classTableauEntiers
{
int*tab_;
inttaille_;
public:
classTailleInvalide{};
intGetTaille()const{returntaille_;}
intoperator[](constintn)const{returntab_[n];}
int&operator[](constintn){returntab_[n];}
TableauEntiers(constinttaille)throw(TailleInvalide,bad_alloc)
:tab_(0),taille_(Taille)
{
if(taille_<=0)throwTailleInvalide();
tab_=newint[GetTaille()];//lvebad_alloc
}
~TableauEntiers()
{delete[]tab_;}
};
473
Exemple:
Unautrecasexceptionnelseraitceluiounindexinvalideestpassaux
oprateurs[]constantetnonconstant.Danscecas,l'exceptionpourraitse
nommerHorsBornes.
Lastratgieestlammequecelledployeplushaut.
classHorsBornes{};
//.............
if(n<0||n>=GetTaille())
throwHorsBornes();
474
TableauEntiers(constintTaille)
throw(TailleInvalide,bad_alloc)
:tab_(0),taille_(Taille)
{if(taille_<=0)throwTailleInvalide();
tab_=newint[GetTaille()];
}
~TableauEntiers(){delete[]tab_;}
};
Exemple:
#include<new>
usingstd::bad_alloc;
classTableauEntiers
{
int*tab_;
inttaille_;
public:
classTailleInvalide{};
classHorsBornes{};
intGetTaille()const{returntaille_;}
intoperator[](constintn)constthrow(HorsBornes)
{if(n<0||n>=GetTaille())throwHorsBornes();
returntab_[n];
}
int&operator[](constintn)throw(HorsBornes)
{if(n<0||n>=GetTaille())throwHorsBornes();
returntab_[n];
}
475
Exceptionsetclassesunportraitpluscomplet
Pourcomplterleportrait,ilfautnoterquecertainesmthodesgarantissentne
paslancerd'exceptions.OnpenseenparticulierlamthodeGetTaille()on
pourraitaussipenseraudestructeur,maislesdestructeurspeuventsecomplexifier
avecletemps,etilestsagedegarantirqu'undestructeurnelverapas
d'exceptions.
Indiquerdansleprototyped'unsousprogrammequ'ilnelancerajamais
d'exceptionsefaitparl'ajoutdelaclausethrow()sansnomdetypeentreles
parenthses(doncavecparenthsesvides).
Ceciestunegarantiedescuritprcieuse:l'appelantsaitalorsquel'appel
s'engagenepaslancerd'exceptionsaucoursdesonexcution.
476
Exceptionset....
...constructeurs
Lesystmedesexceptionsestlesystmedetraitementd'erreursemployerpour
desconstructeursd'objet.
...destructeurs
Lesystmedesexceptionsestlesystmedetraitementd'erreursnepasemployer
aveclesdestructeurs.
Enfait,eninformatiquecommedanslavie,ilestbienplussimplededtruireque
deconstruire,etsurtoutalorsqu'onpeutavoirdumalconstruireunemaison,rienne
devraitpouvoirvousempecherdeladtruire...Demme,leconstructeurpeut
reconterungrandnombredeproblmes(ressourcesimpossiblestrouver....),mais
normalementledestructeurnedevraitpasgnrerd'erreur...oualors,c'estgrave,
carcelasignifiequelesystmerefusedercupreruneressource.
477
Exercice
a)Dfiniruneclassevecteurpermettantdecreretdemanipulerunvecteur:
donnes:
nbElem(entier);
adressedunezoneallouedynamiquement.
mthodes:
constructeurvecteur(int);
destructeurvecteur();
oprateurint&operator[](int);
Ecrireunprogrammedessai.
b)Modifiezceprogrammepourtraiterlesdeuxerreursdeprogrammation:
*constructeuravecunnombrengatifenparamtre;
*appeldeloprateur[]avecunindicetropgrandoungatif.
478