C++ 异常处理(二)

时间:2022-12-12 20:02:58

1. 标准异常

C++标准库中定义一组类,用于报告在标准库中的函数遇到的问题。程序员以在自己编写的程序中使用这些标准异常类。标准库异常类定义在四个头文件中:

①exception头文件中定义了最常见的异常类,类名是exception,这个类只通知异常的产生,不会提供更多的信息

②stdexcept头文件中定义了以下几个异常类:runtime_error, range_error, overflow_error, underflow_error,logic_error, domain_error, invalid_argument, length_error, out_of_range

③new头文件中定义了bad_alloc异常类型

④type_info头文件中定义了bad_cast异常类型

C++ 异常处理(二)

从这幅图中我们也可以看到exception为基类,因此在写catch子句时候必须反映类的层次性。例如

       try
{
//your code
}
catch(overflow_error const &eobj)
{
//your code
}
catch(runtime_error const &re)
{
//your code
}
catch(exception const &e)
{
//your code
}

这里overflow_error类继承runtime_error类,runtime_error类继承exception类,在使用来自继承层次的异常时,catch子句应该从最低派生类型到最到派生类型排序,以便派生类型的处理代码出现在其基类类型的catch之前。

class exception
{ public:
exception();//默认构造函数
exception(char *);//字符串作参数的构造函数
exception(const exception&);
exception& operator= (const exception&);
virtual ~exception();//虚析构函数
virtual char * what() const;//what()虚函数
private:
char * m_what;
};

exception 类型所定义的唯一操作是一个名为what 的虚成员,该函数返回const char* 对象,它一般返回用来在抛出位置构造异常对象的信息。因为 what是虚函数,如果捕获了基类类型引用,对 what 函数的调用将执行适合异常对象的动态类型的版本。

2.调用new失败了怎么办?

无论您是否相信,即使有一个非常庞大的存储器和非常复杂的操作系统,而可以作为空闲的存储空间的存储单元总是很有限的。因此,在使用new时程序可能会超过这个空闲的存储空间。如果确实发生了这种情况,那么operatornew()的调用将会抛出一个std::bad_alloc 类型的异常,它是一个在头文件new 中定义的类。因此我们可捕获这一异常。

#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{

try
{
double *p=new double[0xeffffff];
}
catch(std::bad_alloc const &ba)// 捕获抛出的异常
{
cout<<ba.what()<<endl;
}
system("pause");
return 0;
}
如果不想 让new 抛出异常怎么办?

int _tmain(int argc, _TCHAR* argv[])
{

double *p=new(std::nothrow) double[0xeffffff];

if(p)
{
delete p;
}
else
{
cout<<"out of memory"<<endl;
}
system("pause");
return 0;
}

这样做就不会抛出异常了,如果分配内存失败operator new 会返回一个空指针,而不是抛出std::bad_alloc类型的异常。