Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Exceptions to the programming rules, Part 1

Learn how exception handling has evolved from C to Java

  • Print
  • Feedback

Page 4 of 7

C++'s reserved word throw followed by a class name specifies an intention to throw an object. The idea is for C++ to create an object from that class and throw the object to C++'s runtime code. The runtime code searches backwards through the function call stack -- from most recently called function to least recently called function -- for a function that contains a catch clause capable of catching objects of the thrown object's class type. When found, execution passes to code found within the catch clause. For example, throw DivideByZero (); creates an object from DivideByZero and throws that object to the runtime code. That code searches the function call stack (backwards) for a function containing catch (DivideByZero). If found, execution passes to code within that clause.

To put throwing and catching objects into perspective, look at Listing 3's excdemo.cpp (C++) source code:

Listing 3. excdemo.cpp

// ==============================
// excdemo.cpp
//
// C++ exception demo
//
// Created with: Borland C++ 4.52
// ==============================
#include <iostream.h>
class Stack
{
   int size, top, *values;
   class Parent
   {
      int index, value;
      public:
      Parent (int index, int value)
      {
         this->index = index;
         this->value = value;
      }
      int getIndex ()
      {
         return index;
      }
      int getValue ()
      {
         return value;
      }
   };
   public:
   class Empty : public Parent
   {
      public:
      Empty (int index) : Parent (index, 0)
      {
      }
   };
   class Full : public Parent
   {
      public:
      Full (int index, int value) : Parent (index, value)
      {
      }
   };
   Stack (int size)
   {
      this->size = size;        // Maximum number of integer values in stack.
      top = -1;                 // Stack defaults to empty.
      values = new int [size];  // Create stack to hold size integer values.
   }
   Stack ()
   {
      delete [] values;         // Destroy constructor-created integer array.
   }
   int isEmpty ()
   {
      return (top == -1) ? 1 : 0;
   }
   void push (int value)
   {
      if (top >= size-1)        // When top equals size-1, the stack is full.
          throw Full (top, value); // When full, throw Stack::Full exception.
      values [++top] = value;
   }
   int pop ()
   {
      if (top < 0)              // When top less than 0, the stack is empty.
          throw Empty (top);    // When empty, throw Stack::Empty exception.
      return values [top--];
   }
};
void main ()
{
   Stack s (5); // Create a stack that holds 5 integer values (maximum).
   cout << "Stack object created. Stack holds a maximum of 5 integer values.\n";
   int values [6] = { 52, -32, 468, 345, 42, 91 };
   try
   {
       // Attempt to push 6 integer values onto the stack. The last push attempt
       // results in a Stack::Full exception.
       for (int i = 0; i < 6; i++)
       {
            cout << "Attempting to push integer value " << values [i] << ".\n";
            s.push (values [i]);
       }
   }
   catch (Stack::Full f)
   {
       cout << "Stack is full. Could not push integer value " << f.getValue ()
            << ". Top index equals " << f.getIndex () << ".\n";
   }
   try
   {
       // Attempt to pop 6 values from the stack. The last pop attempt results
       // in a Stack::Empty exception.
       for (int i = 0; i < 6; i++)
            cout << "Popping integer value " << s.pop () << ".\n";
   }
   catch (Stack::Empty e)
   {
       cout << "Stack is empty. Could not pop integer value. Top index equals "
            << e.getIndex () << ".\n";
   }
}


excdemo consists of a top-level Stack class and a main() function. Stack objects represent stack data structures. Those last-in/first-out data structures help programs keep track of things. For example, the function call stack helps C++ track the order in which functions call functions. (I explore stacks and data structures in a future article.) The main() function provides the program's entry point. When excdemo starts running, control passes to main(), which produces the following output:

  • Print
  • Feedback

Resources