C++标准库异常类继承层次中的根类为exception,其定义在exception头文件中,它是C++标准库所有函数抛出异常的基类,exception的接口定义如下:
namespace std {
class exception {
public:
exception() throw(); //不抛出任何异常
exception(const exception& e) throw();
exception& operator= (const exception& e) throw();
virtual ~exception() throw)();
virtual const char* what() const throw(); //返回异常的描述信息
};
}
除了exception类,C++还提供了一些类,用于报告程序不正常的情况,在这些预定义的类中反映的错误模型中,主要包含逻辑错误和运行时错误两大类。
逻辑错误主要包括invalid_argument, out_of_range, length_error, domain_error。当函数接收到无效的实参,会抛出invaild_argument异常,如果函数接收到超出期望范围的实参,会抛出out_of_range异常,等等。
namespace std {
class logic_error: public exception {
public:
explicit logic_error(const string &what_arg);
};
class invalid_argument: public logic_error {
public:
explicit invalid_argument(const string &what_arg);
};
class out_of_range: public logic_error {
public:
explicit out_of_range(const string &what_arg);
};
class length_error: public logic_error {
public:
explicit length_error(const string &what_arg);
};
class domain_error: public logic_error {
public:
explicit domain_error(const string &what_arg);
};
}
运行时错误由程序域之外的事件引发,只有在运行时才能检测,主要包括range_error, overflow_error, underflow_error。函数可以通过抛出range_eroor报告算术运算中的范围错误,通过抛出overflow_error报告溢出错误。
namespace std {
class runtime_error: public exception {
public:
explicit runtime_error(const string &what_arg);
};
class range_error: public runtime_error {
public:
explicit range_error(const string &what_arg);
};
class overflow_error: public runtime_error {
public:
explicit overflow_error(const string &what_arg);
};
class underflow_error: public runtime_error {
public:
explicit underflow_error(const string &what_arg);
};
}
另外,在new头文件中定义了bad_alloc异常,exception也是bad_alloc的基类,用于报告new操作符不能正确分配内存的情形。当dynamic_cast失败时,程序会抛出bad_cast异常类,其也继承自exception类。
以上均是转载于内容。
下面我附上代码,希望有助于读者理解。
我自己设计的异常类,通过虚函数实现的多态,来动态的确定异常的种类:
#include <iostream>
using namespace std;
const int DefaultSize = 10;
class Array
{
public:
Array(int _size = DefaultSize)
:Size(_size)
{
if (_size == 0)
{
throw Xzero(_size);
}
else if (_size < 0)
{
throw XNegative(_size);
}
else if (_size < 10)
{
throw TooSmall(_size);
}
else if (_size > 30000)
{
throw TooBig(_size);
}
pType = new int[_size];
for (int i = 0;i < _size;++i)
{
pType[i] = 0;
}
}
class xError{};
class ErrorSize
{
public:
//异常类的定义
ErrorSize(){}
ErrorSize(int size)
:XSize(size)
{}
virtual ~ErrorSize(){}
int GetXSize() { return XSize; }
virtual void PrintError() = 0;
protected:
int XSize;
};
class Xzero:public ErrorSize
{
public:
Xzero(int size):ErrorSize(size){}
virtual void PrintError()
{
cout << "下标不能是 0, " << "size is : " << XSize << endl;
}
};
class XNegative:public ErrorSize
{
public:
XNegative(int size) :ErrorSize(size) {}
virtual void PrintError()
{
cout << "下标不能是负数 :" << "size is : "<< XSize << endl;
}
};
class TooSmall :public ErrorSize
{
public:
TooSmall(int size):ErrorSize(size)
{}
virtual void PrintError()
{
cout << "下标不能小于10 ," << "size is : " << XSize << endl;
}
};
class TooBig :public ErrorSize
{
public:
TooBig(int size) :ErrorSize(size)
{}
virtual void PrintError()
{
cout << "下标不能大于30000: " << "size is :"<<XSize << endl;
}
};
public:
int GetSize()
{
return Size;
}
int& operator[](int offset)
{
int size = GetSize();
if (offset<0 || offset>=size )
{
throw xError();
}
return pType[offset];
}
~Array()
{
delete []pType;
}
private:
int *pType;
int Size;
};
int main()
{
try
{
Array arr(0);
//Array arr(3000000);
//Array arr(6);
//Array arr(-1);
for (int i = 0;i < 100;i++)
{
arr[i] = i;
cout << " a [" << i << "] is ok" << endl;
}
}
catch (Array::ErrorSize& e)
{
e.PrintError();
}
return 0;
}
运行结果如下: