<!--
    Licensed to the Apache Software  Foundation (ASF) under one or more
    contributor  license agreements.  See  the NOTICE  file distributed
    with  this  work  for  additional information  regarding  copyright
    ownership.   The ASF  licenses this  file to  you under  the Apache
    License, Version  2.0 (the  License); you may  not use  this file
    except in  compliance with the License.   You may obtain  a copy of
    the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the  License is distributed on an  "AS IS" BASIS,
    WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
    implied.   See  the License  for  the  specific language  governing
    permissions and limitations under the License.

    Copyright 1999-2007 Rogue Wave Software, Inc.
-->

<HTML>
<HEAD>
<TITLE>Using Exceptions</TITLE>
<LINK REL=StyleSheet HREF="../rw.css" TYPE="text/css" TITLE="Apache stdcxx Stylesheet"></HEAD>
<BODY BGCOLOR=#FFFFFF>
<A HREF="18-2.html"><IMG SRC="images/bprev.gif" WIDTH=20 HEIGHT=21 ALT="Previous file" BORDER=O></A><A HREF="noframes.html"><IMG SRC="images/btop.gif" WIDTH=56 HEIGHT=21 ALT="Top of Document" BORDER=O></A><A HREF="booktoc.html"><IMG SRC="images/btoc.gif" WIDTH=56 HEIGHT=21 ALT="Contents" BORDER=O></A><A HREF="tindex.html"><IMG SRC="images/bindex.gif" WIDTH=56 HEIGHT=21 ALT="Index page" BORDER=O></A><A HREF="18-4.html"><IMG SRC="images/bnext.gif" WIDTH=25 HEIGHT=21 ALT="Next file" BORDER=O></A><DIV CLASS="DOCUMENTNAME"><B>Apache C++ Standard Library User's Guide</B></DIV>
<H2>18.3 Using Exceptions</H2>
<A NAME="idx427"><!></A>
<P>All exceptions thrown explicitly by any element of the Apache C++ Standard Library are guaranteed to be part of the library's exception hierarchy. Please review the <A HREF="../stdlibref/noframes.html"><I>Apache C++ Standard Library Reference Guide</I></A> entries for these classes to determine which functions throw which exceptions. You can then choose to catch particular exceptions, or catch any that might be thrown by specifying the base class exception. </P>
<P>For instance, if you are going to call the <SAMP>insert</SAMP> function on <B><I><A HREF="../stdlibref/basic-string.html">string</A></I></B> with a position value that could at some point be invalid, you should use code like this:</P>

<UL><PRE>
string s;
int n;
...
try 
{
   s.insert(n,"Howdy");
} 
catch (const std::exception&amp; e)
{
   // deal with the exception
}
</PRE></UL>
<P>To throw your own exceptions, simply construct an exception of an appropriate type, assign it an appropriate message, and throw it. For example:</P>

<UL><PRE>
...
if (n &gt; max)
   throw std::out_of_range("You're past the end, bud");
</PRE></UL>
<P>The class <B><I><A HREF="../stdlibref/exception.html">exception</A></I></B> serves as the base class for all other exception classes. As such it defines a standard interface. This interface includes the <SAMP>what()</SAMP> member function, which returns a null-terminated string that represents the message that was thrown with the exception. This function is likely to be most useful in a catch clause, as demonstrated in the example program in <A HREF="18-4.html">Section&nbsp;18.4</A>.</P>
<P>The class <B><I><A HREF="../stdlibref/exception.html">exception</A></I></B> does not contain a constructor that takes a message string, although it can be thrown without a message. Calling <SAMP>what()</SAMP> on an exception object returns a default message. All classes derived from <B><I>exception</I></B> <I>do</I> provide a constructor that allows you to specify a particular message.</P>
<P>To throw a base exception, you could use the following code:</P>

<UL><PRE>
throw std::exception;
</PRE></UL>
<P>This is generally not very useful, however, since whatever catches this exception has no idea what kind of error has occurred. Instead of a base exception, you will usually throw a derived class such as <B><I><A HREF="../stdlibref/logic-error.html">logic_error</A></I></B> or one of its derivations, such as <B><I><A HREF="../stdlibref/out-of-range.html">out_of_range</A></I></B> in the example above. Better still, you can extend the hierarchy by deriving your own classes. This allows you to provide error reporting specific to your particular problem. For instance:</P>

<UL><PRE>
class bad_packet_error : public std::runtime_error
{
   public:
      bad_packet_error(const std::string&amp; what);
};

if (bad_packet())
   throw bad_packet_error("Packet size incorrect");
</PRE></UL>
<P>This section has demonstrated how the C++ Standard Library exception classes provide you with a basic error model. From this foundation, you can build the right error detection and reporting methods required for your particular application.</P>

<BR>
<HR>
<A HREF="18-2.html"><IMG SRC="images/bprev.gif" WIDTH=20 HEIGHT=21 ALT="Previous file" BORDER=O></A><A HREF="noframes.html"><IMG SRC="images/btop.gif" WIDTH=56 HEIGHT=21 ALT="Top of Document" BORDER=O></A><A HREF="booktoc.html"><IMG SRC="images/btoc.gif" WIDTH=56 HEIGHT=21 ALT="Contents" BORDER=O></A><A HREF="tindex.html"><IMG SRC="images/bindex.gif" WIDTH=56 HEIGHT=21 ALT="Index page" BORDER=O></A><A HREF="18-4.html"><IMG SRC="images/bnext.gif" WIDTH=20 HEIGHT=21 ALT="Next file" BORDER=O></A>

<!-- Google Analytics tracking code -->
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
    _uacct = "UA-1775151-1";
    urchinTracker();
</script>
<!-- end of Google Analytics tracking code -->

</BODY>
</HTML>
