|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#include <iostream>
#include <iostream>
using
namespace
std;
class
FileError{};
class
MemoryError{};
void
foo(
void
)
throw
(MemoryError,FileError,
int
,
double
);
int
main(
void
)
{
try
{
foo();
}
catch
(FileError& ex){
cout <<
"file error!"
<< endl;
return
-1;
}
catch
(MemoryError& ex){
cout <<
"memory error!"
<< endl;
return
-1;
}
catch
(
int
ex&){
//int类型只能捕捉double,同样double只能捕捉double.
cout << ex << endl;
}
catch
(...){
//这里会捕捉所有异常列表的异常对象
cout <<
"other error!"
<< endl;
return
-1;
}
return
0;
}
void
foo(
void
)
throw
(FileError,MemoryError,
int
,
double
){
//与函数声明一样,不多不少.
throw
-1;
//throw FileError();
}
|
异常说明:
1)可以在函数原型中增加异常说明,说明该函数所有可能抛出的异常类型.
返回类类型 函数名(形参表)throw(对象1,对象2,...);(这里对象可以为基本类型)
对象1,对象2...被称为异常说明表
2)函数的异常说明是一种承诺,表示函数所抛出的异常不会超出异常说明表,如果超出,将无法被捕获
即使catch中接受对象的类型也无法被捕获,最终会被系统捕获,终止程序.
3)throw;表示可以抛出任何异常,thow();表示不会抛出异常
4)如果函数申明和定义分开,如果声明时有异常说明,则定义时也要有异常说明,异常说明表要一模一样,
当然,异常说明表中异常对象的位置可以随意.
5)如果基类中的虚函数带有异常说明,那么该函数在子类中的覆盖版本不能在异常说明表中抛出的异常对象不能比基类多(属于包含关系)
6)如果构造函数中抛出异常,则对象将不会调用析构函数(怎么都不会调用),这时需要手动销毁在异常之前
7)不允许在析构函数中抛出异常,如果你在析构中抛异常,这个类一旦实例化,就报错.
所有动态分配的资源.
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include <iostream>
using
namespace
std;
class
A{
public
:
A():m_p(
new
int
(5)){
cout <<
"A:A()"
<< endl;
delete
m_p;
throw
-1;
//析构函数不会调用,抛出异常前,手动释放动态分配的内存
}
~A(){
cout <<
"haha"
<< endl;
delete
m_p;
}
private
:
int
* m_p;
};
int
main(
void
){
A a;
//这样就直接报错.
return
0;
}
|
本文转自神ge 51CTO博客,原文链接:http://blog.51cto.com/12218412/1869629