try{
open the file;
determine its size;
allocate that much memory;
read the file into memory;
close the file;
} catch(fileOpenFailed){
doSomething;
} catch(sizedDeterminationFailed){
doSomething;
} catch(memoryAllocateFailed){
doSomething;
} catch(readFailed){
doSomething;
} catch(fileCloseFailed){
doSomething;
}
template <class T>
class Vector{
private:
T* m_elements;
int m_size;
public:
Vector(int size=0):m_size(size)...
~Vector(){delete [] m_elements}
void length(int);
int length(){return m_size;}
T& operator[] (int);
};
//如果index越界,怎么办?
template <class T>
T& Vector<T>::operator[](int index){
if(index<0||index>=m_size){
//throw is a keyword
//exception is raised at this point
throw <<something>>;
}
return m_elements[index];
}
class VectorIndexError{
public:
VectorIndexError(int v):m_badValue(v){ }
~VectorIndexError(){ }
void diagnostic(){
cerr<<"index"<<m_badValue<<"out of range!";
}
private:
int m_badValue;
};
template <class T>
T& Vector<T>::operator[](int index){
if(index<0||index>=m_size){
//VectorIndexError e(index);
//throw e;
throw VectorIndexError(index);//存放在堆栈里
}
return m_elements[index];
}
//有且仅有new出来的东西在堆里
//全局变量,静态本地变量,静态成员变量在全局数据区里
//本地变量,在函数内部产生的对象在堆栈里
int func(){
Vector<int> v(12);
v[3]=5;
int i=v[42]; //越界,会抛出异常,相当于throw,执行完之后,判断所处位置(为函数),则函数之后的语句不被执行,直接离开函数,带着VectorIndexError(index);来到func()被调用的地方。
return i*5;
}
void outer(){
try{
func();func2(); //func()出了异常,之后的func2()不会被执行
}catch(VectorIndexError& e){ //捕捉&处理VectorIndexError(index);
e.diagnostic(); //进行处理,处理完不回去了,直接执行下面的语句cout<<"Control is here after exception"
}
cout<<"Control is here after exception"
}
void outer2(){
String err("exception caught");
try{
func();
}catch(VectorIndexError){
cout<<err;
throw; //无法解决问题,所以将刚刚捕捉到的异常给扔掉,扔给outer3,让其他catch里的内容处理,这叫做异常的传播
}
}
void outer3(){
try{
outer2();
}catch(...){
//...意味着捕捉所有异常
cout<<"The exception stops here!";
}
}
//一直传播,直到异常能够被解决
try{ ... }
catch ...
catch ...
//catch至少要有一个
catch(SomeType v){
}
catch(...){ //虽然可以处理所有异常,但是接收不到异常对象,因此,尽量少用
}
class MathErr{
...
virtual void diagnostic();
};
class OverflowErr:public MathErr{ ... }
class UnderflowErr:public MathErr{ ... }
class ZeroDivideErr:public MathErr{ ... }
try{
//...
throw UnderFlowErr();
}catch(ZeroDivideErr& e){
//处理ZeroDivideErr抛出的异常
}catch(MathErr& ){
//处理MathErr抛出的异常
}catch(...){ //如果写catch(UnderFlowErr& e)则编译不通过,因为UnderFlowErr是MathErr的子类,同理,如果把catch(...)放在第一个,则编译也不会通过
//处理其他所有的异常
}
void abc(int a):throw(MathErr){//有可能抛出MathErr异常,但是肯定不会抛出MathErr以外的异常,如果抛出其他异常,会给出一个异常unexpected
...
}
void abc(int a){//可以抛出任何异常
...
}
struct B{
virtual void print(){ }
};
struct D:public B{ };
try{
throw D("D error");
}
catch(B& b){
b.print(); //输出D的错误
}