Free Trial

Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.


  • Create BookmarkCreate Bookmark
  • Create Note or TagCreate Note or Tag
  • DownloadDownload
  • PrintPrint
Share this Page URL
Help

Chapter 11. Exception Handling > Creating Your Own Exception Types

Creating Your Own Exception Types

You’ve already seen how all the exception types are derived from the System::Exception class. If you can’t find one that suits your needs in the standard exception hierarchy, you can easily derive your own class from Exception and use it in your code. The following exercise shows you how to derive a new exception class and how to use it in code.

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

2.
Add the following class definition immediately after the using namespace System; line:

// User-defined exception class
__gc class MyException : public System::Exception
{
public:
    int errNo;
    MyException(String* msg, int num) : Exception(msg), errNo(num) {}
};

This custom exception class is a managed class that inherits from System::Exception, and it extends Exception by adding a single field to hold an error number. The class constructor takes a message and a number, and passes the message string back to the base class.

Note

I’ve made the errNo field public. Although you’re normally advised to make all data members of classes private, you can make a case for having public data members in certain circumstances. Once you’ve created an Exception object and passed it back to the client, do you care what the client does with it? Exceptions are “fire and forget” objects, and you’re normally not concerned with the integrity of their state once they leave your code in a throw statement.

3.
Add the following function definition immediately after the class definition:

void func(int a)
{
    try
    {
        if (a <= 0)
            throw new System::ArgumentException(
               S"Negative argument");
    }
    catch(System::ArgumentException* pex)
    {
        Console::WriteLine(S"Caught ArgumentException"
                S"in func()");
        throw new MyException(pex->Message, 1000);
    }
}

The function checks its argument and throws a System::ArgumentException if it finds a negative value. This exception is caught locally, and a message is printed. Now I decide that I really want to handle the exception elsewhere, so I create a new MyException object and rethrow it, initializing it with the message from the original ArgumentException.

4.
Test the exception handling by calling the function in the program’s _tmain routine.

int _tmain()
{
    Console::WriteLine(S"Custom Exceptions");
    try
    {
        func(0);
    }
    catch(MyException* pex)
    {
        Console::WriteLine(S"Caught MyException in main()");
        Console::WriteLine(S"Message is : {0}",
                           pex->Message);
        Console::WriteLine(S"Error number is : {0}",
                           __box(pex->errNo));
    }

    return 0;
}

Calling the function with a 0 value triggers the exception, which is handled in the function itself, and the exception is then rethrown to be handled in the _tmain function. You can see from the following figure how the exception has been caught in both in places.

In the preceding code, notice that it’s necessary to box the error number before it can be used in a call to WriteLine because the formatted overloads to WriteLine need a list of Object* pointers, and boxing lets you use a built-in type as an object. See Chapter 25 for more information on boxing.


  

You are currently reading a PREVIEW of this book.

                                                                                        

Get instant access to over
$1 million worth of books and videos.

  

Start a Free Trial


  
  • Safari Books Online
  • Create BookmarkCreate Bookmark
  • Create Note or TagCreate Note or Tag
  • DownloadDownload
  • PrintPrint