Throwing Exceptions


I’ll start our exploration of exceptions by discussing how to generate, or throw, them. You’ll end up generating far more exceptions by accident than by design, but you need to know how to generate your own when errors occur in your application.

start sidebar
What Can You Throw?

Traditional C++ lets you attach any type of object to an exception, so you can use built-in types (such as int and double) as well as structures and objects. If you throw objects in C++, you usually throw and catch them by reference.

Managed C++ extends this ability to let you throw and catch pointers to managed types, and you’ll most likely be using managed types when you’re writing .NET code. This chapter deals almost exclusively with throwing and catching managed types, but be aware that you’ll meet other data types that are being used out in the wider C++ world.

end sidebar

How do you know what to throw? There are a large number of exception classes as part of the System namespace, all of which derive from Exception. A number of those you’ll commonly encounter are listed in the following table. You should be able to find the exception class to suit your purposes, and if you can’t, it’s always possible to derive your own exception classes from System::Exception.

Exception Class

Description

System::ApplicationException

Thrown when a non-fatal application error occurs.

System::ArgumentException

Thrown when one of the arguments to a function is invalid. Subclasses include System::ArgumentNullException and System::ArgumentOutOfRangeException.

System::ArithmeticException

Thrown to indicate an error in an arithmetic, a casting, or a conversion operation. Subclasses include System::DivideByZeroException and System::OverflowException.

System::Exception

The base class of all exception types.

System::IndexOutOfRangeException

Thrown when an array index is out of range.

System::InvalidCastException

Thrown when an invalid cast or conversion is attempted.

System::MemberAccessException

Thrown when an attempt is made to dynamically access a member that doesn’t exist. Subclasses include System::MissingFieldException and System::MissingMethodException.

System::NotSupportedException

Thrown when a method is invoked that isn’t supported.

System::NullReferenceException

Thrown when an attempt is made to dereference a null reference.

System::OutOfMemoryException

Thrown when memory cannot be allocated.

System::SystemException

The base class for exceptions that the user can be expected to handle. Subclasses include ArgumentException and ArithmeticException.

System::TypeLoadException

Thrown when the common language runtime (CLR) cannot find an assembly or a type within an assembly, or cannot load the type. Subclasses include System::DllNotFoundException.

The following exercise will show you how to generate an exception. In the next section, you’ll go on to see how to catch and process the exception.

  1. Start Microsoft Visual Studio .NET, and open a new Microsoft Visual C++ Console Application (.NET) project named Throwing.

  2. Immediately after the using namespace System; line and immediately before _tmain, add the following function definition:

    void func(int a) { if (a <= 0) throw new System::ArgumentException(S"Aaargh!"); }

    This simple function takes an integer argument, and if its value is less than 0, it throws an exception. In this case, I’m creating a new System::ArgumentException object, initializing it with a string, and then throwing it.

  3. Add code to test out the function by adding this code to the _tmain function:

    Console::WriteLine(S"Throw Test"); Console::WriteLine(S"Calling with a=3"); func(3); Console::WriteLine(S"Calling with a=0"); func(0); Console::WriteLine(S"All done");

    The code calls the function twice, once with a valid value and once with 0, which should trigger the exception.

  4. If you are using Visual C++ 7.1, you need to make one further change before building the program; you don’t need to make this change if you’re using version 7. Use Solution Explorer to open the AssemblyInfo.cpp file, and add the following lines to the file, immediately after the two using namespace lines:

    using namespace System::Diagnostics; [assembly:Debuggable(true, true)];

    These lines ensure that full information is generated when the exception is caught.

    Note

    NoteMicrosoft changed how exception information is generated between the 7 and 7.1 releases. By default, the 7.1 release does not provide full information about where the exception occurred, which is done for efficiency reasons. You can make sure that the full information is generated by adding the Debuggable attribute to AssemblyInfo.cpp, as shown here in Step 4.

  5. Compile and run the code, and you should get a screen that looks like the following figure.

    click to expand

    The program has called the function once without incident, but the second call has triggered an exception. As before, you get a message and a stack trace. This time the message is the string used to initialize the exception object and the stack trace has two levels, showing that the exception was triggered at line 13 in the func function, which was called from the _tmain function at line 27.

Note

The precise line number you get reported in the exception stack trace will depend on exactly how you typed in and formatted your code.




Microsoft Visual C++  .NET(c) Step by Step
Microsoft Visual C++ .NET(c) Step by Step
ISBN: 735615675
EAN: N/A
Year: 2003
Pages: 208

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net