# 王老师 C++ 异常处理

1.throw 表达式

Terminate函数，终止程序的执行。

2.try-catch语句

try{

包含可能抛出异常的语句；

}catch(类型名 [形参名]){

}catch(类型名 [形参名]){

}

#include <iostream>
#include <math.h>

using namespace std;

double sqrt_delta(double d){
if(d < 0)
throw 1;
return sqrt(d);
}

double delta(double a, double b, double c){
double d = b * b - 4 * a * c;
return sqrt_delta(d);
}

void main()
{
double a, b, c;
cout << "please input a, b, c" << endl;
cin >> a >> b >> c;

while(true){
try{
double d = delta(a, b, c);
cout << "x1: " << (d - b) / (2 * a);
cout << endl;
cout << "x2: " << -(b + d) / (2 * a);
cout << endl;
break;
}catch(int){
cout << "delta < 0, please reenter a, b, c.";
cin >> a >> b >> c;
}
}
}

3.重新抛出异常

#include <iostream>
using namespace std;

void fun(int x){
try{
if(x == 1)
throw 1;
if(x == 2)
throw 1.0;
if(x == 3)
throw '1';
}catch(int){
cout << "catch an int in fun()" << endl;
}catch(double){
cout << "catch an double in fun()" << endl;
}
cout << "testing exception in fun()..."<< endl;
}

void gun()
{
try{
//fun(1);
//fun(2);
//fun(3);
fun(4);
}catch(char){
cout << "catch a char in gun()" << endl;
}
cout << "testing exception in gun()..."<< endl;
}

int main()
{
gun();
}

4.扑获所有异常

catch(...){

}

error C2311: 'int' : is caught by '...' on line 7

#include <iostream>
using namespace std;

void fun()
{
try{
}catch(...){
cout << "catch all exception ..." << endl;
}catch(int){
cout << "catch int exception ..." << endl;
}
}

5.异常规范

warning C4297: 'function' : function assumed not to throw an exception but does
__declspec(nothrow) or throw() was specified on the function

#include <iostream>
using namespace std;

void function(int x) throw()
{
if(x == 1)
throw 1;
}

warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)

void function(int x) throw (int)
{
if(x == 1)
throw 1.5;
}

#include <iostream>
using namespace std;

void function(int x)throw(int)
{
if(x == 1)
throw 1;
}

int main()
{
void (*fp)(int)throw(char);
fp = function;
fp(1);
}

warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)

<补充>

#include <iostream>
using namespace std;
class A
{
};

void function(int x)throw(int)
//void function(int x)throw(A*)
{
if(x == 1)
throw new A;
}

void test() throw (A* )
{
//void (*fp)(int)throw(A);
void (*fp)(int)throw(int);
fp = function;
try{
fp(1);
}catch(int)
{
cout << "test" << endl;
throw;
}
}

int main()
{
try{
test();
}catch(A*){
cout << "test in main" <<endl;
}
return 0;
}

<补充>
1.异常处理仅仅通过类型而不是通过值来匹配的，否则又回到了传统的错误处理技术上去了，所以catch块的参数可以没有参数名称，只需要参数类型，除非要使用那个参数。
2.虽然异常对象看上去像局部对象，但并非创建在函数栈上，而是创建在专用的异常栈上，因此它才可以跨接多个函数而传递到上层，否则在栈清空的过程中就会被销毁。
3.函数原型中的异常说明要与实现中的异常说明一致，否则容易引起异常冲突。由于异常处理机制是在运行时有异常时才发挥作用的，因此如果函数的实现中抛出了没有在其异常说明列表中列出的异常，则编译器并不能检查出来。但是当运行时如果真的抛出了这样的异常，就会导致异常冲突。因为你没有提示函数的调用者：该函数会抛出一种没有被说明的即不期望的异常，于是异常处理机制就会检测到这个冲突并调用标准库函数unexcepted()，unexcepted()的默认行为就是调用terminate()来结束程序。

4.当异常抛出时局部对象如何释放？
Bjarne Stroustrup引入了“resource acquistion is initialization”思想，异常处理机制保证：所有从try到throw语句之间构造起来的局部对象的析构函数将被自动调用，然后清退堆栈（就像函数正常退出一样）。如果一直上溯到main函数后还没有找到匹配的catch块，那么系统调用terminate()终止整个程序，这种情况下不能保证所有局部对象会被正确地销毁。
5.catch块的参数应采用引用传递而不是值传递，不仅可以提高效率，还可以利用对象的多态性。另外，派生类的异常扑获要放到父类异常扑获的前面，否则，派生类的异常无法被扑获。catch(void *)要放到catch(...)前面。
6.编写异常说明时，要确保派生类成员函数的异常说明和基类成员函数的异常说明一致，即派生类改写的虚函数的异常说明至少要和对应的基类虚函数的异常说明相同，甚至更加严格，更特殊。

• 本文已收录于以下专栏：

## C++异常处理机制总结

• MulinB
• 2007年08月29日 10:07
• 2268

## C++异常处理的理解

1.异常的基本概念和选择 异常处理try语句会导致比较大的开销，异常规范也会导致比较多的开销（每个都比自己原来大概增大5%-10%左右，速度也减慢原来同等的比例，原因是需要额外的内存和计算来详细记录...
• Blues1021
• 2015年04月18日 08:15
• 754

## 深入理解C++中的异常处理机制

• zhangyifei216
• 2015年12月26日 21:29
• 3066

## JAVA异常处理 与C++的不同

*Java异常处理模型   对于一个非常熟悉 C++ 异常处理模型的程序员来说，它几乎可以不经任何其它培训和学习，就可以完全接受和能够轻松地使用 Java 语言中的异常处理编程方法。这是因为 Java...
• ljlove2008
• 2008年10月14日 23:32
• 2472

## C++异常处理实例

/************************************************************************************************ *...
• JarvisChu
• 2011年07月22日 22:41
• 4027

## 对使用 C++ 异常处理应具有怎样的态度？

http://www.zhihu.com/question/22889420 来自知乎 陈硕，Linux C++程序员，muduo 网络库作者 王召京...
• wangyin159
• 2015年06月28日 08:21
• 565

## C++ 异常处理例子

#include #include #include using namespace std; #ifdef _WIN32 //#include #include #end...
• earbao
• 2016年11月25日 11:59
• 252

## C/C++异常处理的对比

• yeming81
• 2010年06月16日 00:19
• 4699

## Unix/Linux C++应用开发-异常以及错误处理

• wangfengwf
• 2013年09月11日 21:15
• 30142

## C++技术点积累(6)——异常处理、输入和输出流

C++技术点积累： 1、异常处理机制： 2、输入和输出流：
• songshiMVP1
• 2015年09月20日 15:51
• 714

举报原因： 您举报文章：王老师 C++ 异常处理 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)