SUMMARY
This article describes how to use structured exception
handling in Microsoft Visual C++ .NET or in Microsoft Visual C++ 2005.
back
to the topRequirements
The following list outlines the recommended hardware,
software, network infrastructure, and service packs that you need:
- Visual C++ .NET or Visual C++ 2005
This article assumes that you are familiar with the
following topics:
- Visual C++ .NET or Visual C++ 2005
- Microsoft Visual Studio .NET or Microsoft Visual Studio 2005
back to the
topStructured Exception Handling
In Visual C++ .NET or in Visual C++ 2005, you can use structured exception handling for a powerful and a more readable way to handle errors. By using structured
exception handling, you can nest error handlers inside other error
handlers that are in the same procedure. Structured exception handling uses a
block syntax that is similar to the
If...Else...End If statement. Therefore, Visual C++ .NET or Visual C++ 2005 code is more readable and easier to maintain. You can handle
exceptions in Visual C++ .NET or in Visual C++ 2005 by using a combination of the following exception handling
statements:
The basic syntax of structured error handling is as
follows:
try
{
// Code that is expected to raise an exception.
}
catch(Exception *ex)
{
// Code that can handle an error.
}
__finally
{
// Code to do any final cleanup.
}
You can include any valid Visual C++ code in the
try block, or you can include another
try block or another hierarchy of
try blocks. When an exception occurs at any point, the common
language runtime looks for the nearest try block that encloses this code and
does not run any additional lines of code. The control is then passed to a
matching
catch block, if one exists, and to the associated
__finally block. You can also specify multiple
catch statements so that each
catch block handles a specific error.
back to the topCatch an Exception
- Start Visual Studio
.NET or Visual Studio 2005.
- On the File menu, point to
New, and then click Project.
- In Visual Studio .NET 2002, click Visual C++ Projects under Project Types, and then click Managed C++ Application under Templates.
In Visual Studio .NET 2003, click Visual C++ Projects under Project Types, and then click Console Application (.NET) under Templates.
Note In Visual Studio 2005, click Visual C++ under Project Types, and then click Console Application under Templates. - In the Name text box, type
MyConsoleApp.
- In the Location text box, type
C:\, and then click OK.
- In Solution Explorer, double-click MyConsoleApp.cpp to open the Code window. Replace the existing code with the following code in the
main() function:
int a = 0;
int b = 10;
int c = 0;
try
{
a = b / c;
}
catch (Exception *ex)
{
Console::WriteLine(S"A run-time error occurred.");
Console::WriteLine(ex->Message);
}
__finally
{
Console::ReadLine();
}
return 0;
- On the Debug menu, click
Start to run the application. The code tries to divide the number by 0. This operation is not valid and it causes a divide-by-zero error.
However, the catch block catches this error, and you receive the following error message in the Console window:
A run-time error
occurred.
Attempted to divide by zero
- Close the Console window.
back to the
topCatch Multiple Exceptions
This section describes how to use multiple
catch
statements to handle different errors.
- Open the console application project that you created in
the Catch an Exception section of
this article.
- Replace the existing code in the main() function with the
following code:
try
{
//will throw an exception if something goes wrong...
FileStream *fs = File::Open(S"c:\\FileNotFound.txt", FileMode::Open);
}
catch (FileNotFoundException *fe)
{
//give information specific to this exception...
Console::WriteLine(S"Could not find the file, in the specified directory.");
Console::WriteLine(S"Exception : {0}",fe->Message);
}
catch (Exception *ex)
{
//all OTHER scenarios...
Console::WriteLine(S"exception ... {0}",ex->Message);
}
__finally
{
Console::ReadLine();
}
return 0;
This code includes two catch blocks:
- One catch block that catches the FileNotFoundException
exception.
- One catch block that catches all other
exceptions.
- Use the using directive on the System::IO namespace so that you do not have to
qualify declarations from this namespaces later in your code. You must use the
following statement to perform file operations before any other declarations:
using namespace System::IO;
Note The IO namespace contains types that permit synchronous and
asynchronous reading and writing on data streams and files. - On the Debug menu, click
Start to run the application.
- Close the Console window.
- Because you cannot always anticipate every error that may
occur, you can add a catch block for all exceptions that you cannot anticipate. For example,
add the following code before the __finally statement to catch any errors that you cannot anticipate and to
display the appropriate error message:
catch (Exception *ex)
{
Console::WriteLine(S"exception ... {0}",ex->Message);
}
- On the File menu, click Close
Solution.
back to the
topThrow an Exception
Structured exception handling uses the
catch statement to catch an exception. With structured exception
handling, you can also throw an exception. For example, you may find it useful
to throw an exception when you perform data validation inside a
Property Set function, because you may want to throw an error if a business
rule is violated.
- Start Visual Studio .NET or Visual Studio 2005.
- On the File menu, point to New, and then click Project.
- In Visual Studio .NET 2002, click Visual C++ Projects under Project Types, and then click Managed C++ Console Application under Templates.
In Visual Studio .NET 2003, click Visual C++ Projects under Project Types, and then click Console Application (.NET) under Templates.
In Visual Studio 2005, click Visual C++ under Project Types, and then click Console Application under Templates. - In the Name text box, type
MyNewConsoleApp.
- In the Location textbox, type
C:\, and then click OK.
- On the View menu, click Class
View. Right-click MyNewConsoleApp, point to Add, and then
click Add Class.
- Under
Templates in the Add Class dialog box, click Generic C++ Class,
and then click Open.
Note In Visual Studio 2005, click Add. - In Generic C++ Class Wizard, type clsPerson, and then click
Finish.
The clsPerson class appears as follows: #pragma once
class clsPerson
{
public:
clsPerson(void);
~clsPerson(void);
};
To make the clsPerson class as the managed C++ class, add the __gc keyword in front of the clsPerson class. The modified code is as follows:#pragma once
__gc class clsPerson
{
public:
clsPerson(void);
~clsPerson(void);
};
- Add the following code in the clsPerson class:
private:
int mintAge;
public:
__property int get_Age(void)
{
return mintAge;
}
__property void clsPerson::set_Age(int value)
{
if(value > 0)
mintAge = value;
else
throw new System::ArgumentException(S"Age cannot be negative.");
}
This code creates an Age property. Because a person cannot have a negative age, an error
is raised if the user of the class tries to set the Age property to a number that is less than 0. - In Solution Explorer, double-click MyNewConsoleApp.cpp to open the Code window, and then add the following declaration:
#include "clsPerson.h"
- In the main() function of MyNewConsoleApp.cpp, replace the existing code with the following code:
clsPerson *p1 = new clsPerson();
clsPerson *p2 = new clsPerson();
try
{
p1->Age = 60;
Console::WriteLine(S"Age of Person1 = {0}",p1->Age.ToString());
p2->Age = -1;
Console::WriteLine(S"Age of Person2 = {0}",p2->Age.ToString());
}
catch (Exception *e)
{
Console::WriteLine(e->Message);
}
__finally
{
Console::ReadLine();
}
return 0;
- On the Debug menu, click
Start to run the application. You receive the following error message in the Console window:
Age of Person1 = 60
Age
cannot be negative.
- Close the Console window.
back to the
topComplete Code Listing
Catch an Exception
#include <tchar.h>
#using <mscorlib.dll>
using namespace System;
int main()
{
int a = 0;
int b = 10;
int c = 0;
try
{
a = b / c;
}
catch (Exception *ex)
{
Console::WriteLine(S"A run-time error occurred.");
}
__finally
{
Console::ReadLine();
}
return 0;
}
Note You must add the common language runtime support compiler option (/clr:oldSyntax) in Visual C++ 2005 to successfully compile the previous code sample.
To add the common language runtime support compiler option in Visual C++ 2005, follow these steps:
- Click Project, and then click <ProjectName> Properties.
Note <ProjectName> is a placeholder for the name of the project. - Expand Configuration Properties, and then click General.
- Click to select Common Language Runtime Support, Old Syntax (/clr:oldSyntax) in the Common Language Runtime support project setting in the right pane, click Apply, and then click OK.
For more information about the common language runtime support compiler option, visit the following Microsoft Web site:
Catch Multiple Exceptions
#include <tchar.h>
#using <mscorlib.dll>
using namespace System;
using namespace System::IO;
int _tmain()
{
try
{
//will throw an exception if something goes wrong...
FileStream *fs = File::Open(S"c:\\a1.txt", FileMode::Open);
}
catch (FileNotFoundException *fe)
{
//give information specific to this exception...
Console::WriteLine(S"Could not find the file, in the specified directory.");
Console::WriteLine(S"Exception : {0}",fe->Message);
}
catch (Exception *ex)
{
//all OTHER scenarios...
Console::WriteLine(S"exception ... {0}",ex->Message);
}
__finally
{
Console::ReadLine();
}
return 0;
}
Throw an Exception
#include <tchar.h>
#using <mscorlib.dll>
using namespace System;
#pragma once
__gc class clsPerson
{
public:
clsPerson(void)
{
}
~clsPerson(void)
{
}
private:
int mintAge;
public:
__property int get_Age(void)
{
return mintAge;
}
__property void clsPerson::set_Age(int value)
{
if(value > 0)
mintAge = value;
else
throw new System::ArgumentException(S"Age cannot be negative.");
}
};
int _tmain()
{
clsPerson *p1 = new clsPerson();
clsPerson *p2 = new clsPerson();
try
{
p1->Age = 60;
Console::WriteLine(S"Age of Person1 = {0}",p1->Age.ToString());
p2->Age = -1;
Console::WriteLine(S"Age of Person2 = {0}",p2->Age.ToString());
}
catch (Exception *e)
{
Console::WriteLine(e->Message);
}
__finally
{
Console::ReadLine();
}
return 0;
}
back to the
top