c++ primer plus 第15章友,异常和其他,15.3.8exception 类
c++ primer plus 第15章友,异常和其他,15.3.8exception 类
15.3.8exception 类
15.3.8exception 类
C++异常的主要目的是为设计容错程序提供语言级支持,即异常使得在程序设计中包含错误处理功能更容易,以免事后采取一些严格的错误处理方式。异常的灵活性和相对方便性激励着程序员在条件允许的情况下在程序设计中加入错误处理功能。总之,异常是这样一种特性:类似于类,可以改变您的编程方式。
较新的 C++编译器将异常合并到语言中。例如,为支持该语言,exception头文件(以前为exception.h或except.h)定义了 exception 类,C++可以把它用作其他异常类的基类。代码可以引发exception 异常,也可以将 exception 类用作基类。有一个名为 what()的虚拟成员函数,它返回一个字符串,该字符串的特征随实现而异。然而,由于这是一个虚方法,因此可以在从exception派生而来的类中重新定义它:
#include <exception>
class bad_hmean :public std::exception
{
public:const char *what()return "bad arguments to hmean()";
};
class bad_gmean :public std::exception
{
public :
const char*what(){return "bad arguments to gmean()";
};
如果不想以不同的方式处理这些派生而来的异常,可以在同一个基类处理程序中捕获它们:
try
{
...
}
catch(std::exception &e)
{
cout <<e.what()<<endl;
}
否则,可以分别捕获它们。
C++库定义了很多基于exception 的异常类型:
1.stdexcept异常类
头文件 stdexcept 定义了其他几个异常类。首先,该文件定义了logic error 和 runtime error 类,它们都是以公有方式从exception 派生而来的:
class logic error:public exception{
public :
explicit logic error(const string& what arg);
...
};
class domain_error :public logic errorpublic :
explicit domain error(const string& what arg);
};
注意,这些类的构造函数接受一个string对象作为参数,该参数提供了方法 what()以 C-风格字符串方式返回的字符数据。
这两个新类被用作两个派生类系列的基类。异常类系列 logic_error 描述了典型的逻辑错误。总体而言,通过合理的编程可以避免这种错误,但实际上这些错误还是可能发生的。每个类的名称指出了它用于报告的错误类型:
- domain error;
- invalid arqument;
- length error;
- out of bounds.
每个类独有一个类似于 logic error 的构造函数,让您能够提供一个供方法 what()返回的字符串。数学函数有定义域(domain)和值域(range)。定义域由参数的可能取值组成,值域由函数可能的返回值组成。例如,正弦函数的定义域为负无穷大到正无穷大,因为任何实数都有正弦值:但正弦函数的值域为-1到+1,因为它们分别是最大和最小正弦值。另一方面,反正弦函数的定义域为-1到+1,值域为-到+"。如果您编写一个函数,该函数将一个参数传递给函数 std:sin(),则可以让该函数在参数不在定义域
-1到+1之间时引发 domain error 异常。异常 invalid argument指出给函数传递了一个意料外的值。例如,如果函数希望接受一个这样的字符串其中每个字符要么是’0’要么是’1’,则当传递的字符串中包含其他字符时,该函数将引发imnvalid_argument 异常。异常 length_error 用于指出没有足够的空间来执行所需的操作。例如,string类的append()方法在合并得到的字符串长度超过最大允许长度时,将引发1engtherror异常。
异常 out of bounds 通常用于指示索引错误。例如,您可以定义一个类似于数组的类,其 operator()[]在使用的索引无效时引发out of bounds 异常。
接下来,runtime_error 异常系列描述了可能在运行期间发生但难以预计和防范的错误。每个类的名称指出了它用于报告的错误类型:
- range error;
- overflow error;
- underflow error.
每个类独有一个类似于 runtime_error 的构造函数,让您能够提供一个供方法 what( )返回的字符串。下溢(underfow)错误在浮点数计算中。一般而言,存在浮点类型可以表示的最小非零值,计算结果比这个值还小时将导致下溢错误。整型和浮点型都可能发生上溢错误,当计算结果超过了某种类型能够表示的最大数量级时,将发生上溢错误。计算结果可能不再函数允许的范围之内,但没有发生上溢或下溢错
误,在这种情况下,可以使用range_error 异常。一般而言,logic_error 系列异常表明存在可以通过编程修复的问题,而runtimeerror 系列异常表明存在无法避免的问题。所有这些错误类有相同的常规特征,它们之间的主要区别在于:不同的类名让您能够分别处理每种异常。另一方面,继承关系让您能够一起处理它们(如果您愿意的话)。例如,下面的代码首先单独捕获 out_ofbounds 异常,然后统一捕获其他logic_error 系列异常,最后统一捕获 exception 异常、runtime error系列异常以及其他从exception派生而来的异常:
try {
...
}
catch(out of bounds &oe)// catch out of bounds error
{...}
catch(logic error &oe)
//catch remaining logic error family
{...}
catch(exception &oe)
//catch runtime error,exception objects
{...}
如果上述库类不能满足您的需求,应该从logic_error或runtime_error 派生一个异常类,以确保您异常类可归入同一个继承层次结构中。
2.bad alloc 异常和 new
对于使用 new 导致的内存分配问题,C++的最新处理方式是让new引发bad_alloc异常。头文件 new包含 bad alloc 类的声明,它是从 exception 类公有派生而来的。但在以前,当无法分配请求的内存量时,new 返回一个空指针。
程序清单 15.13演示了最新的方法。捕获到异常后,程序将显示继承的 what()方法返回的消息(该消息随实现而异),然后终止。
程序清单 15.13newexcp.cpp
// newexcp.cpp -- the bad_alloc exception
#include <iostream>
#include <new>
#include <cstdlib> // for exit(), EXIT_FAILURE
using namespace std;
struct Big
{
double stuff[20000];
};
int main()
{
Big * pb;
try {
cout << "Trying to get a big block of memory:\n";
pb = new Big[10000]; // 1,600,000,000 bytes
cout << "Got past the new request:\n";
}
catch (bad_alloc & ba)
{
cout << "Caught the exception!\n";
cout << ba.what() << endl;
exit(EXIT_FAILURE);
}
cout << "Memory successfully allocated\n";
pb[0].stuff[0] = 4;
cout << pb[0].stuff[0] << endl;
delete [] pb;
// cin.get();
return 0;
}
下面该程序在某个系统中的输出:
Trying to get a big block of memory:Caught the exception!std::bad alloc
在这里,方法what( )返回字符串“std::bad_alloc”
如果程序在您的系统上运行时没有出现内存分配问题,可尝试提高请求分配的内存量。
3.空指针和 new
很多代码都是在 new 在失败时返回空指针时编写的。为处理 new的变化,有些编译器提供了一个标记(开关),让用户选择所需的行为。当前,C++标准提供了一种在失败时返回空指针的new,其用法如下:
int *pi =new(std::nothrow)int;
int *pa = new(std::nowthrow)int[500];
使用这种new,可将程序清单15.13的核心代码改为如下所示:
Big *pb;
pb =new(std::nothrow)Big[10000];//1,600,000,000 bytesif(pb ==0)
cout <<"Could not allocate memory.Bye.n";
exit(EXIT FAILURE);
原文地址:https://blog.csdn.net/zhyjhacker/article/details/140333387
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!