Академический Документы
Профессиональный Документы
Культура Документы
MicrosoftVisualC++/CLI:ExceptionHandling
ExceptionHandling
IntroductiontoExceptions
AnOverview
Imagine you want to write a program that requests a number from the user, multiplies the
numberby2,anddisplaystheresult.Theformofthisprogramcanbedesignedasfollows:
System::VoidbtnCalculate_Click(System::Object^sender,System::EventArgs^e)
{
doublenumber,result
number=double::Parse(txtNumber>Text)
result=number*2
txtResult>Text=result.ToString()
This looks like an easy request. When it comes up, the user is asked to simply type a number.
The number would then be multiplied by 2 and display the result. Imagine that may be the
Numbertext box is empty, or a user types something that is not a valid number, such as the
nameofacountryorsomebodystelephonenumber.Sincethisprogramwasexpecting
anumberanditisnotpreparedtomultiplyastringtoanumber,itwouldproduceanerror.
Whenever the compiler is handed a task, it would try to perform the assignment. If it can
t proceed, for any reason it is not prepared for, it would cause an error. As a
programmer, if you can anticipate the type of error that could occur in your program, you can
catch the error yourself and deal with it by telling the compiler what to do when this type of
erroroccurs.
PracticalLearning:IntroducingExceptionHandling
1.StartanewWindowsFormsApplicationnamedGCS1anddesigntheformasfollows:
http://www.functionx.com/vccli/topics/exceptions.htm
1/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
Control
Name
Text
AdditionalProperties
Form
Size:374,415
Label
CustomerName:
TextBox
txtCustomer1
Label
mm
Label
dd
Label
yyyy
Label
OrderDate:
TextBox
txtMM
TextAlign:Right
TextBox
txtDD
TextAlign:Right
TextBox
txtYYYY
1970
TextAlign:Right
Label
ItemTypes
Label
Qty
Label
UnitPrice
Label
SubTotal
Label
Shirts
TextBox
txtQtyShirts
TextAlign:Right
TextBox
txtUnitPriceShirts
1.05
TextAlign:Right
TextBox
txtSubTotalShirts
0.00
TextAlign:Right
Label
Pants
TextBox
txtQtyPants
TextAlign:Right
TextBox
txtUnitPricePants
2.75
TextAlign:Right
TextBox
txtSubTotalPants
0.00
TextAlign:Right
Label
Dresses
TextBox
txtQtyOther
TextAlign:Right
TextBox
txtUnitPriceOther
4.50
TextAlign:Right
TextBox
txtSubTotalOther
0.00
TextAlign:Right
Button
btnProcess
Process
Label
CustomerName:
TextBox
txtCustomer2
Label
Orderdate:
TextBox
txtOrderDate
Label
TaxRate:
TextBox
txtTaxRate
5.75
Label
Button
btnTax
Tax
http://www.functionx.com/vccli/topics/exceptions.htm
2/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
Label
TotalOrder:
TextBox
txtTotalOrder
0.00
TextAlign:Right
Label
TaxAmount:
TextBox
txtTaxAmount
0.00
TextAlign:Right
Label
NetPrice:
TextBox
txtNetPrice
0.00
TextAlign:Right
Label
AmountTended:
TextBox
txtAmountTended
0.00
TextAlign:Right
Button
btnDifference
Diff
Label
Difference:
TextBox
txtDifference
0.00
TextAlign:Right
2.Toarrangethetabsequence,onthemainmenu,clickView>TabOrder
3.Ontheform,clickonlythefollowingcontrolswhosesquareshaveawhitebackground,inthe
indicatedorder:
4.PressEsc
5.Toprocessanorder,doubleclicktheProcessbuttonandimplementitseventasfollows:
#pragmaonce
namespaceGCS1{
...NoChange
publicrefclassForm1:publicSystem::Windows::Forms::Form
{
public:
Form1(void)
InitializeComponent()
//
//TODO:Addtheconstructorcodehere
//
...NoChange
private:
///<summary>
///Requireddesignervariable.
///</summary>
System::ComponentModel::Container^components
//OrderInformation
http://www.functionx.com/vccli/topics/exceptions.htm
3/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
String^CustomerName
String^mm,^dd,^yyyy
//Quantitiesofitems
intNumberOfShirts
intNumberOfPants
intNumberOfOtherItems
//Priceofitems
doublePriceOneShirt,PriceAPairOfPants,PriceOneOther
//Eachofthesesubtotalswillbeusedforcleaningitems
doubleSubTotalShirts,SubTotalPants,SubTotalOthers
//Valuesusedtoprocessanorder
doubleTaxRate
doubleTotalOrder,TaxAmount,SalesTotal
#pragmaregionWindowsFormDesignergeneratedcode
///<summary>
///RequiredmethodforDesignersupportdonotmodify
///thecontentsofthismethodwiththecodeeditor.
///</summary>
voidInitializeComponent(void)
...NoChange
}
#pragmaendregion
private:System::VoidbtnProcess_Click(System::Object^sender,
System::EventArgs^e)
{
if(this>btnProcess>Text==L"Process")
{
//Requestorderinformationfromtheuser
CustomerName=this>txtCustomer1>Text
mm=this>txtMM>Text
dd=this>txtDD>Text
yyyy=this>txtYYYY>Text
//Requestthequantityofeachcategoryofitems
//NumberofShirts
NumberOfShirts=int::Parse(this>txtQtyShirts>Text)
//NumberofPants
NumberOfPants=int::Parse(this>txtQtyPants>Text)
//NumberofDresses
NumberOfOtherItems=int::Parse(this>txtQtyOther>Text)
//UnitPricesofitems
PriceOneShirt=double::Parse(this>txtUnitPriceShirts>Text)
PriceAPairOfPants=double::Parse(this>txtUnitPricePants>Text)
PriceOneOther=double::Parse(this>txtUnitPriceOther>Text)
//Performthenecessarycalculations
SubTotalShirts=NumberOfShirts*PriceOneShirt
SubTotalPants=NumberOfPants*PriceAPairOfPants
SubTotalOthers=NumberOfOtherItems*PriceOneOther
this>txtSubTotalShirts>Text=SubTotalShirts.ToString(L"C")
this>txtSubTotalPants>Text=SubTotalPants.ToString(L"C")
this>txtSubTotalOther>Text=SubTotalOthers.ToString(L"C")
//Calculatethe"temporary"totaloftheorder
TotalOrder=SubTotalShirts+SubTotalPants+SubTotalOthers
//Displaythereceipt
this>txtCustomer2>Text=CustomerName
this>txtOrderDate>Text=String::Concat(mm,L"/",dd,L"/",yyyy)
this>txtTotalOrder>Text=TotalOrder.ToString(L"C")
this>Height=416
this>btnProcess>Text="Reset"
}
else
{
this>Height=240
this>txtCustomer1>Text=""
http://www.functionx.com/vccli/topics/exceptions.htm
4/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
this>txtMM>Text="1"
this>txtDD>Text="1"
this>txtYYYY>Text="1970"
this>txtQtyShirts>Text="0"
this>txtQtyPants>Text="0"
this>txtQtyOther>Text="0"
this>txtSubTotalShirts>Text="$0.00"
this>txtSubTotalPants>Text="$0.00"
this>txtSubTotalOther>Text="$0.00"
}
}
this>btnProcess>Text="Process"
6.DoubleclicktheTaxbuttonandimplementitseventasfollows:
System::VoidbtnTax_Click(System::Object^sender,
System::EventArgs^e)
{
//Getthetaxrate
TaxRate=double::Parse(this>txtTaxRate>Text)/100
//Calculatethetaxamountusingaconstantrate
TaxAmount=TotalOrder*TaxRate
//Addthetaxamounttothetotalorder
SalesTotal=TotalOrder+TaxAmount
this>txtTaxAmount>Text=TaxAmount.ToString(L"C")
this>txtNetPrice>Text=SalesTotal.ToString(L"C")
7.DoubleclicktheDiffbuttonandimplementitseventasfollows:
System::VoidbtnDifference_Click(System::Object^sender,
System::EventArgs^e)
{
doubleAmountTended,Difference
//Requestmoneyfortheorder
AmountTended=double::Parse(this>txtAmountTended>Text)
//Calculatethedifferenceowedtothecustomer
//orthatthecustomerstillowestothestore
Difference=AmountTendedSalesTotal
this>txtDifference>Text=Difference.ToString(L"C")
8.Resizetheformtoappearasfollows:
9.Toexecutetheapplication,ontheStandardtoolbar,clicktheStartWithoutDebuggingbutton
http://www.functionx.com/vccli/topics/exceptions.htm
5/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
10.Deletethevalueinthequantityandtypew
11.ClickProcess
12.ClickQuitandclosetheformtoreturntoyourprogrammingenvironment
ExceptionalBehaviors
An exception is an unusual situation that could occur in your program. As a programmer, you
http://www.functionx.com/vccli/topics/exceptions.htm
6/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
should anticipate any abnormal behavior that could be caused by the user entering wrong
information that could otherwise lead to unpredictable results. The ability to deal with a
programs eventual abnormal behavior is called exception handling. The C/C++
language provides four main keywords to handle an exception. At thistime,wewillreviewtwo
ofthem:tryandcatch.
1.Tryingthenormalflow:Todealwiththeexpectedbehaviorofaprogram,youusethetry
keywordasinthefollowingsyntax:
try{Behavior}
Thetrykeywordisrequired.Itletsthecompilerknowthatyouareattemptinganormalflow
ofyourprogram.Theactualbehaviorthatneedstobeevaluatedisincludedbetweenan
openingcurlybracket{andaclosingcurlybracket}.Inside
ofthebrackets,implementthenormalflowthattheprogrammustfollow,atleastforthis
sectionofthecode.Hereisanexample:
System::VoidbtnCalculate_Click(System::Object^sender,
System::EventArgs^e)
{
doublenumber,result
try{
number=double::Parse(txtNumber>Text)
result=number*2
txtResult>Text=result.ToString()
2.CatchingErrors:Duringtheflowoftheprogramaspartofthetrysection,ifanabnormal
behavioroccurs,insteadoflettingtheprogramcrashorinsteadoflettingthecompilersend
theerrortotheoperatingsystem,youcantransfertheflowoftheprogramtoanother
sectionthatcandealwithit.Thesyntaxusedbythissectionis:
catch{WhatToDo}
This section always follows the try section. There must not be any code between the trys
closingbracketandthecatchsection.Thecatchkeywordisrequiredandfollowsthetrysection.Unlike
try,catchalwaysappearslikeafunction.Thatis,thecatch keyword always has parentheses. Unlike a
normalfunction,catchmustalwaysreceiveanargument.Ifyoudon'thaveanargumenttopass,then
youcantypethreeperiodsintheparentheses.Eventually,wewillknowwhattypesofargumentscanbe
passedtocatchandwewillknowwhatthethreeperiodsmean.
Combinedwiththetryblock,thebasicsyntaxofanexceptionwouldbe:
try
{
//Trytheprogramflow
}
catch(...)
{
//Catchtheexception
}
Aprogramthatincludesacatchsectionwouldappearasfollows:
System::VoidbtnCalculate_Click(System::Object^sender,System::EventArgs^e)
{
doublenumber,result
try{
txtResult>Text=result.ToString()
}
catch(...)
{
}
number=double::Parse(txtNumber>Text)
result=number*2
PracticalLearning:IntroducingVagueExceptions
1.Tointroduceexceptions,accesstheform'scodeandchangetheeventsofthebuttonsas
follows:
http://www.functionx.com/vccli/topics/exceptions.htm
7/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
System::VoidbtnProcess_Click(System::Object^sender,
System::EventArgs^e)
{
if(this>btnProcess>Text==L"Process")
{
//Requestorderinformationfromtheuser
CustomerName=this>txtCustomer1>Text
mm=this>txtMM>Text
dd=this>txtDD>Text
yyyy=this>txtYYYY>Text
//Requestthequantityofeachcategoryofitems
//NumberofShirts
try{
NumberOfShirts=int::Parse(this>txtQtyShirts>Text)
}
catch(...)
{
}
//NumberofPants
try{
NumberOfPants=int::Parse(this>txtQtyPants>Text)
}
catch(...)
{
}
//NumberofDresses
try{
NumberOfOtherItems=int::Parse(this>txtQtyOther>Text)
}
catch(...)
{
}
//UnitPricesofitems
...NoChange
System::VoidbtnTax_Click(System::Object^sender,System::EventArgs^e)
{
//Getthetaxrate
try{
TaxRate=double::Parse(this>txtTaxRate>Text)/100
//Calculatethetaxamountusingaconstantrate
TaxAmount=TotalOrder*TaxRate
//Addthetaxamounttothetotalorder
SalesTotal=TotalOrder+TaxAmount
this>txtTaxAmount>Text=TaxAmount.ToString(L"C")
this>txtNetPrice>Text=SalesTotal.ToString(L"C")
}
catch(...)
{
}
}
System::VoidbtnDifference_Click(System::Object^sender,
System::EventArgs^e)
{
doubleAmountTended,Difference
//Requestmoneyfortheorder
try{
AmountTended=double::Parse(this>txtAmountTended>Text)
//Calculatethedifferenceowedtothecustomer
//orthatthecustomerstillowestothestore
Difference=AmountTendedSalesTotal
this>txtDifference>Text=Difference.ToString(L"C")
}
catch(...)
{
}
http://www.functionx.com/vccli/topics/exceptions.htm
8/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
}
2.Executetheapplication.Thistime,typeinvalidvaluesinthequantitytextboxesandother
textboxeswheretheuserissupposedtoentersomevalues
3.ClickProcess
4.Closetheformandreturntoyourprogrammingenvironment
ExceptionsandCustomMessages
As mentioned already, if an error occurs when processing the program in the try section, the
compilertransferstheprocessingtothenextcatchsection.Youcanthenusethecatchsectionto
deal with the error. At a minimum, you can display a message to inform the user. Here is an
example:
System::VoidbtnCalculate_Click(System::Object^sender,System::EventArgs^e)
{
doublenumber,result
try{
txtResult>Text=result.ToString()
}
catch(...)
{
lblMessage>Text=L"InvalidNumber"
}
number=double::Parse(txtNumber>Text)
result=number*2
http://www.functionx.com/vccli/topics/exceptions.htm
9/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
Of course, your message may not be particularly clear but this time, the program would not
crash.
PracticalLearning:DisplayingCustomMessages
1.Todisplaycustommessagestotheuser,changetheform's(header)fileasfollows:
System::VoidbtnProcess_Click(System::Object^sender,
System::EventArgs^e)
{
if(this>btnProcess>Text==L"Process")
{
//Requestorderinformationfromtheuser
CustomerName=this>txtCustomer1>Text
mm=this>txtMM>Text
dd=this>txtDD>Text
yyyy=this>txtYYYY>Text
//Requestthequantityofeachcategoryofitems
//NumberofShirts
try{
NumberOfShirts=int::Parse(this>txtQtyShirts>Text)
}
catch(...)
{
MessageBox::Show(L"Thevalueyoutypedforthenumberof"
L"shirtsisnotavalidnumber."
L"\nPleaseenteranaturalnumber"
Lsuchas2or24oreven248")
}
//NumberofPants
try{
NumberOfPants=int::Parse(this>txtQtyPants>Text)
}
catch(...)
{
MessageBox::Show(L"Thevalueyoutypedforthenumberof"
L"pairorpantsisnotavalidnumber."
L"\nPleaseenteranaturalnumbersuchas2or24oreven248")
}
//NumberofDresses
try{
NumberOfOtherItems=int::Parse(this>txtQtyOther>Text)
}
catch(...)
{
MessageBox::Show(L"Thevalueyoutypedforthenumberof"
L"dressesisnotavalidnumber."
L"\nPleaseenteranaturalnumbersuchas2or24oreven248")
}
//UnitPricesofitems
try{
PriceOneShirt=double::Parse(this>txtUnitPriceShirts>Text)
}
catch(...)
{
MessageBox::Show(L"Thevalueyouenteredfortheunitpriceof"
L"ashirtisnotarecognizablecurrencyamount."
L"\nOnlynaturalordecimalnumbersareallowed."
L"Pleaseconsultthemanagementtoknowthevalidprices.")
}
try
{
http://www.functionx.com/vccli/topics/exceptions.htm
10/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
PriceAPairOfPants=double::Parse(this>txtUnitPricePants>Text)
}
catch(...)
{
MessageBox::Show(L"Thevalueyouenteredfortheunitpriceof"
L"apairofpantsisnotarecognizablecurrencyamount."
L"\nOnlynaturalordecimalnumbersareallowed."
L"Youcanconsultthemanagementtofindoutabout"
L"theallowableprices.")
}
try
{
PriceOneOther=double::Parse(this>txtUnitPriceOther>Text)
}
catch(...)
{
MessageBox::Show(L"Thevalueyouenteredfortheunitpriceof"
L"adressisnotavalidamount."
L"\nYoumustenteronlyanaturaloradecimalnumber."
L"Formoreinformation,pleaseconsultthemanagementtoget"
L"therightprices.")
}
...NoChange
}
else
{
...NoChange
}
}
private:System::VoidbtnTax_Click(System::Object^sender,
System::EventArgs^e)
{
//Getthetaxrate
try{
TaxRate=double::Parse(this>txtTaxRate>Text)/100
//Calculatethetaxamountusingaconstantrate
TaxAmount=TotalOrder*TaxRate
//Addthetaxamounttothetotalorder
SalesTotal=TotalOrder+TaxAmount
this>txtTaxAmount>Text=TaxAmount.ToString(L"C")
this>txtNetPrice>Text=SalesTotal.ToString(L"C")
}
catch(...)
{
MessageBox::Show(L"Thevalueyouenteredisnotrecognized"
L"asavalidtaxrate."
L"\nAvalidtaxrateisavaluebetween0and100.00"
L"\nPleasetryagain.")
}
}
private:System::VoidbtnDifference_Click(System::Object^sender,
System::EventArgs^e)
{
doubleAmountTended,Difference
//Requestmoneyfortheorder
try{
AmountTended=double::Parse(this>txtAmountTended>Text)
//Calculatethedifferenceowedtothecustomer
//orthatthecustomerstillowestothestore
Difference=AmountTendedSalesTotal
this>txtDifference>Text=Difference.ToString(L"C")
}
catch(...)
{
MessageBox::Show(L"Thevalueyouenteredfortheamount"
L"tendedisnotvalid."
L"Onlynaturalordecimalnumbersareallowed."
L"Pleasetryagain.")
http://www.functionx.com/vccli/topics/exceptions.htm
11/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
}
}
2.Testtheapplicationwithvalidandinvalidvalues.Hereisanexample:
3.Closetheformandreturntoyourprogrammingenvironment
Exceptionsinthe.NETFramework
TheExceptionClass
With C/C++, you can create any exception of your choice, including numeric or strings. So far,
to handle exceptions, we were passing three periods to the catch clause. The three periods are
tellingthecompilerthatweknowthatanerrorislikelytooccurbutwedon'tknowwhattypeof
erroritwouldbe.Therefore,thethreeperiodsareusedforlackofmoreinformation.
To customize exception handling, you can even create your own class(es). Before you do this,
the.NETFrameworkprovidesaspecialclasscalledException.Oncethecompilerencountersan
error, the Exception class allows you to identify the type of error and take an appropriate
action.
Exception mostly serves as the general class of exceptions. Based on this, in an application,
insteadofthethreeperiods,youcanpassanExceptionhandletothecatchclause.Hereisan
example:
System::VoidbtnCalculate_Click(System::Object^sender,System::EventArgs^e)
{
doublenumber,result
try{
txtResult>Text=result.ToString()
}
catch(Exception^)
{
lblMessage>Text=L"InvalidNumber"
}
number=double::Parse(txtNumber>Text)
result=number*2
PassinganException argument to catch is still a general way to catch an unknown but likely
exception.Anticipatingvarioustypesofproblemsthatcanoccurinaprogram,Microsoftcreated
variousotherclassestomakethisissuefriendlier.Asaresult,almostanytypeofexceptionyou
mayencounteralreadyhasaclasscreatedtodealwithit.Therefore,whenyourprogramfaces
anexception,youcaneasilyidentifythetypeoferror.Therearesomanyexceptionclassesthat
wecannot study or review them all. The solution we will use is to introduce or review a class
whenwemeetitstypeoferror.
TheException'sMessage
When an exception occurs in the try section, code compilation is transferred to the catch
http://www.functionx.com/vccli/topics/exceptions.htm
12/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
section.IfyoudeclaretheexceptionasanExceptiontype,thisclasswillidentifytheerror.One
ofthepropertiesoftheExceptionclassiscalledMessage.Thispropertycontainsastringthat
describesthetype of error that occurred. You can then use this Exception::Messageproperty
todisplayanerrormessageifyouwant.Hereisanexample:
System::VoidbtnCalculate_Click(System::Object^sender,System::EventArgs^e)
{
doublenumber,result
try{
txtResult>Text=result.ToString()
}
catch(Exception^e)
{
lblMessage>Text=e>Message
}
number=double::Parse(txtNumber>Text)
result=number*2
CustomErrorMessages
Asyoucansee,oneofthestrengthsoftheException::Messagepropertyisthatitgivesyoua
good indication of the type of problem that occurred. Sometimes, the message provided by the
Exception class may not appear explicit enough. In fact, you may not want to show it to the
usersince,asinthiscase,theusermaynotunderstandwhattheexpression"correctformat"in
this context means and why it is being used. As an alternative, you can create your own
messageanddisplayittotheuser.Hereisanexample:
System::VoidbtnCalculate_Click(System::Object^sender,System::EventArgs^e)
{
doublenumber,result
try{
txtResult>Text=result.ToString()
}
catch(Exception^)
{
lblMessage>Text=L"Theoperationcouldnotbecarried"
}
number=double::Parse(txtNumber>Text)
result=number*2
YoucanalsocombinetheException::Messagemessageandyourownmessage:
private:System::Voidbutton1_Click(System::Object^sender,
System::EventArgs^e)
{
doublenumber,result
http://www.functionx.com/vccli/topics/exceptions.htm
13/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
try{
textBox2>Text=result.ToString()
}
catch(Exception^e)
{
MessageBox::Show(String::Concat(e>Message,
L"Theoperationcouldnotbecarriedbecause"
L"thenumberyoutypedisnotvalid"))
}
number=textBox1>Text>ToDouble(0)
result=number*2
AReviewof.NETExceptionClasses
Introduction
The .NET Framework provides various classes to handle almost any type of exception you can
think of. There are so many of these classes that we can only mention the few that we will
regularlyuseinourapplications.
Therearetwomainwaysyoucanuseoneoftheclassesofthe.NETFramework.Ifyouknowfor
sure that a particular exception will be produced, pass its handle to a catch() clause but you
don't have to name the handle: you just have to indicate that the class is passed as a handle.
Then,inthecatch()section,displayacustommessage.Thesecondoptionyouhaveconsistsof
using the throw keyword. We will try to always indicate the type of exception that could be
thrownifsomethinggoeswronginaprogram.
TheFormatExceptionException
Everything the user types into a control using the keyboard is primarily a string and you must
convertittotheappropriatetypebeforeusingit.Whenyourequestaspecifictypeofvaluefrom
theuser,aftertheuserhastypeditandyoudecidetoconvertittotheappropriatetype,ifyour
conversion fails, the program produces (we will use the word "throw") an error. The error is
fromtheFormatExceptionclass.
HereisaprogramthatdealswithaFormatExceptionexception:
System::VoidbtnCalculate_Click(System::Object^sender,System::EventArgs^e)
doublenumber,result
try{
txtResult>Text=result.ToString()
}
catch(FormatException^)
{
lblMessage>Text=L"Theoperationcouldnotbecarried"
}
number=double::Parse(txtNumber>Text)
result=number*2
http://www.functionx.com/vccli/topics/exceptions.htm
14/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
PracticalLearning:UsingtheFormatExceptionClass
1.Changetheform'sfileasfollows:
System::VoidbtnProcess_Click(System::Object^sender,
System::EventArgs^e)
{
if(this>btnProcess>Text==L"Process")
{
...NoChange
try{
NumberOfShirts=int::Parse(this>txtQtyShirts>Text)
}
catch(FormatException^)
{
...NoChange
}
//NumberofPants
try{
NumberOfPants=int::Parse(this>txtQtyPants>Text)
}
catch(FormatException^)
{
...NoChange
}
//NumberofDresses
try{
NumberOfOtherItems=int::Parse(this>txtQtyOther>Text)
}
catch(FormatException^)
{
...NoChange
}
//UnitPricesofitems
try{
PriceOneShirt=double::Parse(this>txtUnitPriceShirts>Text)
}
catch(FormatException^)
{
...NoChange
}
try
{
PriceAPairOfPants=double::Parse(this>txtUnitPricePants>Text)
}
catch(FormatException^)
{
MessageBox::Show(L"Thevalueyouenteredfortheunitpriceof"
L"apairofpantsisnotarecognizablecurrencyamount."
L"\nOnlynaturalordecimalnumbersareallowed."
L"Youcanconsultthemanagementtofindoutabout"
L"theallowableprices.")
}
try
{
PriceOneOther=double::Parse(this>txtUnitPriceOther>Text)
}
catch(FormatException^)
{
...NoChange
}
http://www.functionx.com/vccli/topics/exceptions.htm
15/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
...NoChange
private:System::VoidbtnTax_Click(System::Object^sender,
System::EventArgs^e)
{
//Getthetaxrate
try{
...NoChange
}
catch(FormatException^)
{
...NoChange
}
}
private:System::VoidbtnDifference_Click(System::Object^sender,
System::EventArgs^e)
{
doubleAmountTended,Difference
//Requestmoneyfortheorder
try{
...NoChange
}
catch(FormatException^)
{
...NoChange
}
}
2.Executetheapplicationandreturntoyourprogrammingenvironment
TheOverflowExceptionException
A computer application receives, processes, and produces values on a regular basis as the
program is running. To better manage these values, the compiler uses appropriate amounts of
space to store its values. It is not unusual that either you, the programmer, or a user of your
applicationprovidesanvaluethatisbeyondtheallowedrangeofthedatatype.Forexample,a
byte uses 8 bits to store a value and a combination of 8 bits can store a number no more than
255.Ifyouprovideavaluehigherthan255tobestoredinabyte,yougetanerror.Considerthe
followingprogram:
System::Voidbutton1_Click(System::Object^sender,System::EventArgs^e)
{
BytenumberOfPages
numberOfPages=Byte::Parse(this>textBox1>Text)
this>textBox2>Text=numberOfPages.ToString()
When a value beyond the allowable range is asked to be stored in memory, the compiler
producesanerroroftheOverflowExceptionclass.Hereisanexampleofrunningtheprogram
withabadnumber:
http://www.functionx.com/vccli/topics/exceptions.htm
16/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
Aswiththeothererrors,whenthisexceptionisthrown,youshouldtakeappropriateaction.
TheDivideByZeroExceptionException
Division by zero is an operation to always avoid. It is so important that it is one of the most
fundamentalexceptionsofthecomputer.Itisaddressedatthecorelevelevenbythecomputer
processor. It is addressed by the operating system at its level. It is also addressed by most, if
not all, compilers. It is also addressed by most, if not, all libraries. This means that this
exceptionisneverwelcomedanywhere.The.NETFrameworkalsoprovidesitownclasstoface
thisoperation.
If an attempt to divide a value by 0, the compiler produces a DivideByZeroException
exception.
TechniquesofUsingExceptions
ThrowinganException
As mentioned above, the Exception class is equipped with a Message property that carries a
messagefortheerrorthatoccurred.Wealsomentionedthatthemessageofthispropertymay
notbeparticularlyusefultoauser.Fortunately,youcancreateyourownmessageandpassitto
the Exception. To be able to receive custom messages, the Exception class provides the
followingconstructor:
public:Exception(String^message)
Touseit,inthesectionwhereyouareanticipatingtheerror,typethethrowkeywordfollowed
by a newoperator and an instance of the Exception class using the constructor that takes a
string.Hereisanexample:
System::VoidbtnCalculate_Click(System::Object^sender,System::EventArgs^e)
{
doublenumber1,number2
doubleresult=0.00
String^operation
try{
number1=double::Parse(this>txtNumber1>Text)
operation=this>txtOperation>Text
number2=double::Parse(this>txtNumber2>Text)
if(!operation>Equals(L"+")&&
!operation>Equals(L"")&&
!operation>Equals(L"*")&&
!operation>Equals(L"/"))
throwgcnewException(operation)
if(operation>Equals(L"+"))
result=number1+number2
elseif(operation>Equals(L""))
result=number1number2
elseif(operation>Equals(L"*"))
result=number1*number2
elseif(operation>Equals(L"/"))
result=number1/number2
else
lblMessage>Text=L"BadOperation"
http://www.functionx.com/vccli/topics/exceptions.htm
17/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
this>txtResult>Text=result.ToString()
}
catch(Exception^)
{
lblMessage>Text=L"OperationError:Invalidoperator"
}
CatchingVariousExceptions
In the above examples, when we anticipated some type ofproblem,weinstructedthecompiler
to use our default catch section. We left it up to the compiler to find out when there was a
problemandweprovidedacatch section to deal with it. A function with numerous or complex
operationsandrequestscanalsoproducedifferenttypesoferrors.Withsuchatypeofprogram,
you should be able to face different problems and deal with them individually, each by its own
kind.Todothis,youcancreatedifferentcatch sections, each made for a particularerror.The
formulausedwouldbe:
try{
//CodetoTry
}
catch(Exception1)
{
//OneException
}
catch(Exceptio2)
{
//AnotherException
}
Thecompilerwouldproceedinatopdown:
1.Followingthenormalflowoftheprogram,thecompilerentersthetryblock
2.Ifnoexceptionoccursinthetryblock,therestofthetryblockisexecuted
Ifanexceptionoccursinthetryblock,thecompilerregistersthetypeoferrorthat
occurred.Ifthereisathrowline,thecompilerregistersitalso:
a.Thecompilergetsoutofthetrysection
b.Thecompilerexaminesthefirstcatch.Ifthefirstcatchmatchesthethrownerror,
thatcatchexecutesandtheexceptionhandlingroutinemayseize.Ifthefirstcatch
doesntmatchthethrownerror,thecompilerproceedswiththenextcatch
c.Thecompilerchecksthenextmatch,ifany,andproceedsasinthefirstmatch.This
continuesuntilthecompilerfindsacatchthatmatchesthethrownerror
d.Ifoneofthecatchesmatchesthethrownerror,itsbodyexecutes.Ifnocatchmatches
thethrownerror,thecompilercallstheExceptionclassandusesthedefaultmessage
Multiplecatchesarewritteniforwhenatryblockisexpectedtothrowdifferenttypesoferrors.
For example, in our calculator, we want to consider only the addition, the subtraction, the
multiplication, and the division. It is also likely that the user may type one or two invalid
numbers.Thisleadsustoknowthatourprogramcanproduceatleasttwotypesoferrorsatthis
time.Basedonthis,wecanaddressthemusingtwocatchclausesasfollows:
System::VoidbtnCalculate_Click(System::Object^sender,System::EventArgs^e)
{
doublenumber1,number2
doubleresult=0.00
String^operation
try{
number1=double::Parse(this>txtNumber1>Text)
http://www.functionx.com/vccli/topics/exceptions.htm
18/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
operation=this>txtOperation>Text
number2=double::Parse(this>txtNumber2>Text)
if(!operation>Equals(L"+")&&
!operation>Equals(L"")&&
!operation>Equals(L"*")&&
!operation>Equals(L"/"))
throwgcnewException(operation)
if(operation>Equals(L"+"))
result=number1+number2
elseif(operation>Equals(L""))
result=number1number2
elseif(operation>Equals(L"*"))
result=number1*number2
elseif(operation>Equals(L"/"))
result=number1/number2
else
lblMessage>Text=L"BadOperation"
this>txtResult>Text=result.ToString()
}
catch(FormatException^)
{
lblMessage>Text=L"Youtypedaninvalidnumber."
}
catch(Exception^ex)
{
lblMessage>Text=L"OperationError:Invalidoperator"
}
This program works fine as long as the user types two valid numbers and a valid arithmetic
operator.Anythingelse,suchaninvalidnumberoranunexpectedoperatorwouldcauseanerror
tobethrown:
http://www.functionx.com/vccli/topics/exceptions.htm
19/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
Obviously,variousbadthingscouldhappenwhenthisprogramisrunning.Imaginethattheuser
wants to perform a division. You need to tell the compiler what to do if the user enters the
denominatoras0(or0.00).Ifthishappens,oneoftheoptionsyoushouldconsideristodisplay
amessageandgetout.Fortunately,the.NETFrameworkprovidestheDivideByZeroException
classtodealwithanexceptioncausedbydivisionbyzero.Asdonewiththemessagepassedto
the Exception class, you can compose your own message and pass it to the
DivideByZeroException(stringmessage)constructor.
Exception is the parent of all exception classes. This corresponds to the three periods of a
catch(...) block. Therefore, if you write various catch blocks, the one that takes the three
periods as argument must be the last. If you provide a catch that takes an Exceptionclassas
argument,youcanomitthethreeperiodcatchandprovidetheExceptioncatchasthelast.
PracticalLearning:IdentifyingtheThrownException
1.Tocatchvariousexceptions,changetheform'sfileasfollows:
System::VoidbtnProcess_Click(System::Object^sender,
System::EventArgs^e)
{
if(this>btnProcess>Text==L"Process")
{
//Requestorderinformationfromtheuser
CustomerName=this>txtCustomer1>Text
try{
intmm,dd,yyyy
mm=this>txtMM>Text
dd=this>txtDD>Text
yyyy=this>txtYYYY>Text
//Thisexceptionisthrowniftheusertypesavaluethatcannot
//beconvertedintoavalidnumber
catch(FormatException^ex)
MessageBox::Show(String::Concat(L"Error:",ex.Message,
L"\nThevalueyouentered",
L"isnotavalidnumber")
//Thisexceptionisthrownifthevaluesthatuserhadtypedcannot
//produceavaliddatevalue
catch(ArgumentOutOfRangeException^)
MessageBox::Show(L"Thedateyouenteredisnotvalid"
L"Pleasetryagain!")
//Requestthequantityofeachcategoryofitems
//NumberofShirts
try{
NumberOfShirts=int::Parse(this>txtQtyShirts>Text)
}
catch(FormatException^)
{
MessageBox::Show(L"Thevalueyoutypedforthenumberof"
L"shirtsisnotavalidnumber."
L"\nPleaseenteranaturalnumbersuchas2or24oreven248")
}
//Thisexceptionisthrowniftheusertypesanegativevalue
catch(OverflowException^)
{
MessageBox::Show(L"Thenumberyoutypedisnegativebut"
L"wecannotacceptanegativenumberofshirts")
}
//NumberofPants
try{
NumberOfPants=int::Parse(this>txtQtyPants>Text)
}
catch(FormatException^)
{
MessageBox::Show(L"Thevalueyoutypedforthenumberof"
L"pairorpantsisnotavalidnumber."
L"\nPleaseenteranaturalnumbersuchas2or24oreven248")
}
catch(OverflowException)
http://www.functionx.com/vccli/topics/exceptions.htm
20/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
{
MessageBox::Show(L"Thenumberyoutypedisnegativebut"
L"wecannotacceptanegativenumberofshirts")
}
//NumberofDresses
try{
NumberOfOtherItems=int::Parse(this>txtQtyOther>Text)
}
catch(FormatException^)
{
MessageBox::Show(L"Thevalueyoutypedforthenumberof"
L"otheritemsisnotavalidnumber."
L"\nPleaseenteranaturalnumbersuchas2or24oreven248")
}
catch(OverflowException^)
{
MessageBox::Show(L"Thenumberyoutypedisnegativebut"
L"wecannotacceptanegativenumberofotheritems")
}
//UnitPricesofitems
try{
PriceOneShirt=double::Parse(this>txtUnitPriceShirts>Text)
if(PriceOneShirt<0)
thrownewException(L"Negativenumbersarenot"
L"allowedforthepriceofashirt")
catch(FormatException^)
MessageBox::Show(L"Thevalueyouenteredfortheunitpriceof"
L"ashirtisnotarecognizablecurrencyamount."
L"\nOnlynaturalordecimalnumbersareallowed."
L"Pleaseconsultthemanagementtoknowthevalidprices.")
catch(Exception^ex)
MessageBox::Show(ex>Message)
try
{
PriceAPairOfPants=double::Parse(this>txtUnitPricePants>Text)
if(PriceAPairOfPants<0)
thrownewException(L"Negativenumbersarenotallowed"
L"forthepriceofapairofpants")
}
catch(FormatException^)
{
MessageBox::Show(L"Thevalueyouenteredfortheunitpriceof"
L"apairofpantsisnotarecognizablecurrencyamount."
L"\nOnlynaturalordecimalnumbersareallowed."
L"Youcanconsultthemanagementtofindoutabout"
L"theallowableprices.")
}
catch(Exception^ex)
{
MessageBox::Show(ex>Message)
}
try
{
PriceOneOther=double::Parse(this>txtUnitPriceOther>Text)
if(PriceOneDress<0)
thrownewException(L"Negativenumbersarenotallowed"
L"forthepriceofaitems")
}
catch(FormatException^)
{
MessageBox::Show(L"Thevalueyouenteredfortheunitpriceof"
L"adressisnotavalidamount."
L"\nYoumustenteronlyanaturaloradecimalnumber."
L"Formoreinformation,pleaseconsultthemanagementtoget"
L"therightprices.")
}
catch(Exception^ex)
http://www.functionx.com/vccli/topics/exceptions.htm
21/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
{
MessageBox::Show(ex>Message)
}
//Performthenecessarycalculations
SubTotalShirts=NumberOfShirts*PriceOneShirt
SubTotalPants=NumberOfPants*PriceAPairOfPants
SubTotalOthers=NumberOfOtherItems*PriceOneOther
this>txtSubTotalShirts>Text=SubTotalShirts.ToString(L"C")
this>txtSubTotalPants>Text=SubTotalPants.ToString(L"C")
this>txtSubTotalOther>Text=SubTotalOthers.ToString(L"C")
//Calculatethe"temporary"totaloftheorder
TotalOrder=SubTotalShirts+SubTotalPants+SubTotalOthers
//Displaythereceipt
this>txtCustomer2>Text=CustomerName
this>txtOrderDate>Text=String::Concat(mm,L"/",dd,L"/",yyyy)
this>txtTotalOrder>Text=TotalOrder.ToString(L"C")
this>Height=416
this>btnProcess>Text="Reset"
}
else
{
this>Height=240
this>txtCustomer1>Text=""
this>txtMM>Text="1"
this>txtDD>Text="1"
this>txtYYYY>Text="1970"
this>txtQtyShirts>Text="0"
this>txtQtyPants>Text="0"
this>txtQtyOther>Text="0"
this>txtSubTotalShirts>Text="$0.00"
this>txtSubTotalPants>Text="$0.00"
this>txtSubTotalOther>Text="$0.00"
}
}
this>btnProcess>Text="Process"
System::VoidbtnTax_Click(System::Object^sender,System::EventArgs^e)
{
//Getthetaxrate
try{
TaxRate=double::Parse(this>txtTaxRate>Text)/100
if(PriceOneShirt<0)
thrownewException(L"Negativenumbersarenot"
L"allowedforataxrate")
//Calculatethetaxamountusingaconstantrate
TaxAmount=TotalOrder*TaxRate
//Addthetaxamounttothetotalorder
SalesTotal=TotalOrder+TaxAmount
this>txtTaxAmount>Text=TaxAmount.ToString(L"C")
this>txtNetPrice>Text=SalesTotal.ToString(L"C")
}
catch(FormatException^)
{
MessageBox::Show(L"Thevalueyouenteredisnotrecognized"
L"asavalidtaxrate."
L"\nAvalidtaxrateisavaluebetween0and100.00"
L"\nPleasetryagain.")
}
catch(Exception^ex)
{
MessageBox::Show(ex>Message)
}
}
private:System::VoidbtnDifference_Click(System::Object^sender,
System::EventArgs^e)
{
http://www.functionx.com/vccli/topics/exceptions.htm
22/23
5/5/2016
MicrosoftVisualC++/CLI:ExceptionHandling
doubleAmountTended,Difference
//Requestmoneyfortheorder
try{
AmountTended=double::Parse(this>txtAmountTended>Text)
//Calculatethedifferenceowedtothecustomer
//orthatthecustomerstillowestothestore
Difference=AmountTendedSalesTotal
this>txtDifference>Text=Difference.ToString(L"C")
}
catch(FormatException^)
{
MessageBox::Show(L"Thevalueyouenteredfortheamount"
L"tendedisnotvalid."
L"Onlynaturalordecimalnumbersareallowed."
L"Pleasetryagain.")
}
}
2.Testtheapplicationandreturntoyourprogrammingenvironment
ExceptionsNesting
The calculator simulator we have studied so far performs a division as one of its assignments.
Welearnedthat,inorderto perform any operation, the compiler must first make sure that the
user has entered a valid operator. Provided the operator is one of those we are expecting, we
also must make sure that the user typed valid numbers. Even if these two criteria are met, it
waspossiblethattheuserenter0forthedenominator.Theblockthatisusedtocheckforanon
zero denominator depends on the exception that validates the operators. The exception that
could result from a zero denominator depends on the user first entering a valid number for the
denominator.
Youcancreateanexceptioninsideofanother.Thisisreferredtoasnestinganexception.Thisis
done by applying the same techniques we used to nest conditional statements. This means that
you can write an exception that depends on, and is subject to, another exception. To nest an
exception,writeatry block in the body of the parent exception. The nested try block must be
followedbyitsowncatchclause(s).Toeffectivelyhandletheexception,makesureyouinclude
anappropriatethrowinthetryblock.
Home
Copyright20072011FunctionX
http://www.functionx.com/vccli/topics/exceptions.htm
23/23