Vous êtes sur la page 1sur 42

TraitementdesexceptionsenC++

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

Vous aimerez peut-être aussi