C++抛出的异常可以是各种类型,比如int,long,string,或者是自己定义的类型。而标准库里面抛出的异常都从std::exception类继承下来的,以下是std::exception的定义,
-
class exception {
-
public:
-
exception () noexcept;
-
exception (const exception&) noexcept;
-
exception& operator= (const exception&) noexcept;
-
virtual ~exception();
-
virtual const char* what() const noexcept;
-
}
一般我们在异常处理的代码中会看到*.what()这样的形式,这个what函数就是返回异常的具体信息,我们看一个标准的例子,
-
// exception example
-
#include <iostream> // std::cerr
-
#include <typeinfo> // operator typeid
-
#include <exception> // std::exception
-
-
class Polymorphic {virtual void member(){}};
-
-
int main () {
-
try
-
{
-
Polymorphic * pb = 0;
-
typeid(*pb); // throws a bad_typeid exception
-
}
-
catch (std::exception& e)
-
{
-
std::cerr << "exception caught: " << e.what() << '\n';
-
}
-
return 0;
-
}
这段代码由于对空指针pb调用了typeid,会抛出一个bad_typeid类型的异常,14行的catch捕获到了这个异常,并且显示异常信息。运行程序输出为
exception caught: St10bad_typeid
标准库中有很多种不同的异常,主要分为逻辑错误(logic_error)和运行时错误(runtime_error)两个大类
逻辑错误就是一些程序内部出现逻辑问题的错误,比如下面这段代码,
-
vector<int> aVec(10, 0);
-
try
-
{
-
cout << aVec.at(10) << endl;
-
}
-
catch (out_of_range& e)
-
{
-
cout << "excpetion caught: " << e.what() << endl;
-
}
定义一个int类型的vector,用10个0来初始化,然后读取其第11个元素,程序会抛出一个out_of_range类型的异常,这样的错误就属于典型的逻辑错误,此处多说一句,使用vector的时候尽量都用*.at(index)的形式来存取里面的元素,因为如果越界的话会抛出out_of_range类型的异常,而如果用*[index]的形式来存取元素的话,即使越界,程序的行为也是一种未定义的状态。
运行时错误的定义是只有在运行时才有可能检查出来的错误,而在编译的时候是无法检查出来的错误都算运行时错误。
除了上述两大类的异常,还有两个异常非常常用,他们分别为bad_alloc异常和bad_cast异常。
下面给出他们的具体例子,
-
// bad_alloc example
-
#include <iostream> // std::cout
-
#include <new> // std::bad_alloc
-
-
int main () {
-
try
-
{
-
int* myarray= new int[10000];
-
}
-
catch (std::bad_alloc& ba)
-
{
-
std::cerr << "bad_alloc caught: " << ba.what() << '\n';
-
}
-
return 0;
-
}
bad_alloc异常就是向系统请求分配内存的时候如果出现内存空间不够抛出的异常,类似于C语言中的malloc当内存不够的时候返回NULL。
-
// bad_cast example
-
#include <iostream> // std::cout
-
#include <typeinfo> // std::bad_cast
-
-
class Base {virtual void member(){}};
-
class Derived : Base {};
-
-
int main () {
-
try
-
{
-
Base b;
-
Derived& rd = dynamic_cast<Derived&>(b);
-
}
-
catch (std::bad_cast& bc)
-
{
-
std::cerr << "bad_cast caught: " << bc.what() << '\n';
-
}
-
return 0;
-
}
bad_cast异常时在使用dynamic_cast做转换时发生错误而产生的异常,具体请见C++中运行时绑定(多态)的相关内容。
总之定义一些异常并且在代码中使用它们是很有好处的,可以帮助程序员及时发现问题,而不是到了产品快要发布的时候抓狂的去找一些隐藏了很深而时隐时现的一些问题。
阅读(1138) | 评论(0) | 转发(0) |