<!--
    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>exception</TITLE>
<LINK REL=StyleSheet HREF="../rw.css" TYPE="text/css" TITLE="Apache stdcxx Stylesheet"></HEAD>
<BODY BGCOLOR=#FFFFFF>
<A HREF="equal-to.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="exception-h.html"><IMG SRC="images/bnext.gif" WIDTH=25 HEIGHT=21 ALT="Next file" BORDER=O></A><DIV CLASS="DOCUMENTNAME"><B>Apache C++ Standard Library Reference Guide</B></DIV>
<H2>exception</H2>
<P><B>Library:</B>&nbsp;&nbsp;<A HREF="2-2.html">Language support</A></P>

<PRE><HR><B><I>Does not inherit</I></B><HR></PRE>

<UL>
<LI><A HREF="#sec1">Local Index</A></LI>
<LI><A HREF="#sec2">Summary</A></LI>
<LI><A HREF="#sec3">Synopsis</A></LI>
<LI><A HREF="#sec4">Interface</A></LI>
<LI><A HREF="#sec5">Example</A></LI>
<LI><A HREF="#sec6">Constructors</A></LI>
<LI><A HREF="#sec7">Destructor</A></LI>
<LI><A HREF="#sec8">Public Member Operator</A></LI>
<LI><A HREF="#sec9">Public Member Function</A></LI>
<LI><A HREF="#sec10">See Also</A></LI>
<LI><A HREF="#sec11">Standards Conformance</A></LI>
</UL>
<A NAME="sec1"><H3>Local Index</H3></A>
<H4>Members</H4>
<UL><TABLE CELLPADDING=3>
<TR><TD VALIGN=top>
<A HREF="#idx628">exception()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx631">operator=()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx632">what()</A><BR>
</TD>
<TD VALIGN=top><A HREF="#idx630">~exception()</A><BR>
</TD></TR>
</TABLE></UL>

<A NAME="sec2"><H3>Summary</H3></A>
<P>Class <B><I>exception</I></B> is the base class that supports logic and runtime errors.</P>
<A NAME="sec3"><H3>Synopsis</H3></A>

<PRE>#include &lt;exception&gt;

namespace std {
  class exception;
}
</PRE>
<A NAME="sec4"><H3>Interface</H3></A>

<UL><PRE>namespace std {
      class exception {
      public:
        exception() throw();
        exception(const exception&amp;) throw();
        exception&amp; operator=(const exception&amp;) throw();
        virtual ~exception() throw();
        virtual const char* what() const throw();
      };
}
</PRE></UL>
<A NAME="sec5"><H3>Example</H3></A>

<UL><PRE>//
// except.cpp
//

#include &lt;iostream&gt;
#include &lt;stdexcept&gt;


#ifndef _RWSTD_NO_EXCEPTIONS

int main ()
{
   try {
       // Enable exceptions in cin.
       std::cin.exceptions(std::ios::eofbit);

       // Clear all bits and set eofbit.
       std::cin.clear(std::ios::eofbit);
   }
   catch (const std::ios::failure &amp;e) {
       std::cout &lt;&lt; "Caught an exception: " 
                 &lt;&lt; e.what () &lt;&lt; std::endl;
   }
   catch (const std::exception &amp;e) {
       std::cout &lt;&lt; "Caught an exception: " 
                 &lt;&lt; e.what () &lt;&lt; std::endl;

       return 1;   // Indicate failure.
   }
   catch (...) {
       std::cout &lt;&lt; "Caught an unknown exception" 
                 &lt;&lt; std::endl;

       return 1;   // Indicate failure.
   }

   return 0;
}

#else

int main ()
{
    std::cout &lt;&lt; "Exceptions not supported." &lt;&lt; std::endl;

    return 0;
}


#endif   // _RWSTD_NO_EXCEPTIONS

Program Output:

Caught an exception: std::cin: stream object has set ios::eofbit
</PRE></UL>
<UL><PRE></PRE></UL>
<A NAME="sec6"><H3>Constructors</H3></A>

<A NAME="idx628"></A><PRE><B>exception</B>() throw();</PRE>
<UL>
<P>Default constructor. Constructs an object of class <B><I>exception</I></B>.</P>
</UL>


<A NAME="idx629"></A><PRE><B>exception</B>(const exception&amp;) throw();</PRE>
<UL>
<P>Copy constructor. Copies an <B><I>exception</I></B> object.</P>
</UL>

<A NAME="sec7"><H3>Destructor</H3></A>

<A NAME="idx630"></A><PRE>virtual <B>~exception</B>() throw();</PRE>
<UL>
<P>Destructor. Destroys an object of class <B><I>exception</I></B>.</P>
</UL>

<A NAME="sec8"><H3>Public Member Operator</H3></A>

<A NAME="idx631"></A><PRE>exception&amp; 
<B>operator=</B>(const exception&amp;) throw();</PRE>
<UL>
<P>Assignment operator. Copies an <B><I>exception</I></B> object.</P>
</UL>

<A NAME="sec9"><H3>Public Member Function</H3></A>

<A NAME="idx632"></A><PRE>virtual const char* 
<B>what</B>() const throw();</PRE>
<UL>
<P>Returns an implementation-defined, null-terminated byte string representing a human-readable message describing the exception. The message may be a null-terminated multibyte string, suitable for conversion and display as a <B><I><A HREF="wstring.html">wstring</A></I></B>.</P>
</UL>

<A NAME="sec10"><H3>See Also</H3></A>
<P><A HREF="exceptions.html">Exceptions</A>, <B><I>bad_alloca</I></B>, <B><I><A HREF="bad-cast.html">bad_cast</A></I></B>, <B><I><A HREF="bad-exception.html">bad_exception</A></I></B>, <B><I><A HREF="bad-typeid.html">bad_typeid</A></I></B>, <B><I><A HREF="domain-error.html">domain_error</A></I></B>, <B><I><A HREF="invalid-argument.html">invalid_argument</A></I></B>, <B><I><A HREF="ios-base.html#failure">ios_base::failure</A></I></B>, <B><I><A HREF="length-error.html">length_error</A></I></B>, <B><I><A HREF="logic-error.html">logic_error</A></I></B>, <B><I><A HREF="out-of-range.html">out_of_range</A></I></B>, <B><I><A HREF="overflow-error.html">overflow_error</A></I></B>, <B><I><A HREF="range-error.html">range_error</A></I></B>, <B><I><A HREF="runtime-error.html">runtime_error</A></I></B>, <B><I><A HREF="underflow-error.html">underflow_error</A></I></B></P>
<A NAME="sec11"><H3>Standards Conformance</H3></A>
<P><I>ISO/IEC 14882:1998 -- International Standard for Information Systems --Programming Language C++, Section 19.1</I></P>

<BR>
<HR>
<A HREF="equal-to.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="exception-h.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>
