Вы находитесь на странице: 1из 23

5/5/2016

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

Вам также может понравиться