?? ex21.cpp
字號:
// 第21章 異常處理技術(shù)
// [例21.1] C++異常處理技術(shù)
# include <stdio.h>
long DivThrow(long x,long y)
{ if(y==0) throw x;
return x/y;
}
void ExceptHanding(long u,long v)
{ try
{ long d=DivThrow(u,v);
printf("ExceptHanding %d/%d=%d\n",u,v,d);
}
catch(long x)
{ printf("ExceptHanding=%d. Can't divided by zero\n",x); }
}
void main()
{ ExceptHanding(5,3); //輸出結(jié)果ExceptHanding 5/3=1
ExceptHanding(5,0); //輸出結(jié)果ExceptHanding=5. Can't divided by zero
}
//[例21.2]if語句加靜態(tài)變量的跟蹤
# include <stdio.h>
enum {NoZero=1,IsZero=1000};
static int sTrace=NoZero;
long DivideIf(long x,long y)
{ if(y==0){ sTrace=IsZero; return x; }
return x/y;
}
void TraceHanding(long u,long v)
{ long d=DivideIf(u,v);
switch(sTrace)
{ case NoZero: printf("TraceHanding %d/%d=%d\n",u,v,d);break;
case IsZero: printf("TraceHanding %d. Can't divided by zero\n",d);break;
}
}
void main()
{ TraceHanding(6,2); //輸出結(jié)果TraceHanding 6/2=3
TraceHanding(2,0); //輸出結(jié)果TraceHanding 2. Can't divided by zero
}
//[例21.3] 異常的多路捕獲
# include <stdio.h>
enum enumType {eChars,eLong,eClass,eUnknown,eSkip};
class ClassE{};
struct Unknown{};
void PolyHanding(int kind)
{ if(kind==eSkip) throw eSkip; //這個throw語句匹配外層的try塊
try
{ if(kind==eChars) throw "string type"; //
if(kind==eLong) throw (long)kind;
if(kind==eClass) throw ClassE(); //throw顯式調(diào)用構(gòu)造函數(shù)
if(kind==eUnknown) throw Unknown(); //調(diào)用缺省構(gòu)造函數(shù)Unknown()
}
catch(char* s) { printf("Except Handler is=%s\t",s);}
catch(long) { printf("Except Handler is long type\t");}
catch(ClassE) { printf("Except Handler is ClassE type\t");}
catch(...) { printf("Except Handler is Unknown type\t"); }
printf("Embeded try~catch block is not skip\n");
}
void main()
{ try
{ PolyHanding(eChars); //程序內(nèi)部的異常在內(nèi)部有效處理
PolyHanding(eLong); //流程依次執(zhí)行函數(shù)調(diào)用
PolyHanding(eClass);
PolyHanding(eUnknown); //程序內(nèi)部的異常在內(nèi)部有效處理
PolyHanding(eSkip); //函數(shù)調(diào)用引發(fā)外層try塊的throw語句
PolyHanding(eLong); //這兩個函數(shù)調(diào)用是程序的死碼區(qū)
PolyHanding(eClass);
}
catch(enumType) //攔截梅舉類enumType的異常流
{ printf("Embeded try~catch block is skipped\n"); }
printf("this printf is a must route\n"); //這個printf語句是流程的必由之路
} //輸出如下:
//[例21.4] 異常的重新拋出
# include <stdio.h>
enum {eLong,eUnknown,eSpecial};
struct Unknown{};
class Special{};
void fa(int kind)
{ try {
if(kind==eSpecial) throw Special();
if(kind==eUnknown) throw Unknown();
}
catch(Special) { printf("fa Rethrowing Special Exception out\n");
throw; //相當(dāng)于 throw Special()到上層fb的 catch(Special)入口
}
catch(...) { printf("fa Rethrowing Unknown Exception out\n");
throw; //相當(dāng)于throw Unknown()到上層fb的catch(...)
}
printf("normal process in fa\t");
}
void fb(int kind)
{ try { fa(kind);}
catch(Special)
{ printf("fb Rethrowing Special Exception out\n");
throw; //相當(dāng)于 throw Special()到上層fc的 catch(Special)入口
}
catch(...) { printf("Unknown Exception treated here in fb\n");}
printf("normal process in fb\n");
}
void fc(int kind)
{ try
{ fb(kind);
if(kind==eLong) throw (long)kind;
}
catch(long) { printf("long type Exception is in fc \n");}
catch(Special) { printf("Special Exception is treated here in fc \n");}
}
void main() { fc(eLong); fc(eUnknown); fc(eSpecial); }
//[例21.5]異常過程中對象的清除
#include<stdio.h>
class ClassB
{ public: int m_b;
ClassB(int n=1) {m_b=n;printf("%d.ClassB::ClassB(),this=%p\n",m_b,this);}
~ClassB() { printf("%d.ClassB::~ClassB()\n",m_b);}
};
class ClassC
{ public: int m_c;
ClassC(int n=2) {m_c=n;printf("%d.ClassC::ClassC(),this=%p\n",m_c,this);}
~ClassC() { printf("%d.ClassC::~ClassC()\n",m_c); }
void Show() { printf("Show m_c=%d,this=%p \n",m_c,this); }
};
enum {eObjc=888,eObjh=3};
void fa(int k)
{ if(k==eObjc) {
printf("send local Objc with k=%d\n",eObjc);
throw ClassC(k); //直接拋出一個無名對象
}
ClassB objb(2); //中間定義一個局部對象objb2
ClassC *pObjc=new ClassC(k); //定義一個Heap空間的對象
printf("send Heap obj with k=%d\n",k);
throw pObjc; //無過濾條件的拋出對象指針
printf("this code area is dead block\n"); //死碼區(qū)
delete pObjc;
}
void fb(int k)
{ printf("Enter regular routine with k=%d\n",k);
try{ ClassB objb(1); //定義局部變量objb1
fa(k);
}
catch(ClassC objc ) //接受數(shù)值對象的入口處理器
{ printf("local Objc received\n");
objc.Show();
}
catch(ClassC *p=NULL ) //接受對象指針的入口處理器
{ if(p!=NULL)
{ printf("Heap Obj received\n");
p->Show();
delete p;
}
}
}
void main() { fb(eObjc); fb(eObjh); }
//[例21.6]繼承層次catch處理器的先后次序
#include<stdio.h>
class B
{ public: int m_b;
B (int n=1) {m_b=n;printf("B::B()this=%p\n",this);}
virtual ~B (){printf("B::~B()this=%p\n",this);}
virtual int HandleError();
};
class C : public B
{ public: int m_c;
C() {m_c=2;printf("C::C()this=%p\n",this);}
virtual ~C(){printf("C::~C()this=%p\n",this);}
virtual int HandleError();
};
class D : public C
{ public: int m_d;
D(){m_d=4; printf("D::D()this=%p\n",this);}
virtual ~D(){printf("D::~D()this=%p\n",this);}
virtual int HandleError();
};
int B::HandleError() {printf("B::HandleError()this=%p\n",this);return 1;}
int C::HandleError() {printf("C::HandleError()this=%p\n",this);return 0;}
int D::HandleError() {printf("D::HandleError()this=%p\n",this);return 1;}
enum{classb,classc,classd,etype1,etype2};
int ErrorInfo(int k) //對錯誤消息進(jìn)行分流的函數(shù)
{ switch(k)
{ case etype1: return etype1;
case etype2: return etype2;
default : return etype2+1;
}
}
void ThrowHandler(int k)
{ switch(k) //throw的表達(dá)式先完成副作用
{ case classb: throw B(); //拋出基類的無名對象
case classc: throw C(); //拋出直接派生類對象
case classd: throw D(); //拋出間接派生類對象
default : throw ErrorInfo(k); //拋出其它錯誤消息
}
}
void VirtualHandling(int k)
{ try {ThrowHandler(k); } //拋出兩種類型的異常
catch(B & rBase) { //基對象的引用形參
rBase.HandleError(); //對象別名虛擬調(diào)用虛函數(shù)
}
catch(int k) //捕獲整型數(shù)值類型消息
{ switch(k) //消息根據(jù)具體的數(shù)值分流
{ case etype1: printf("etype1 Error treated here\n");break;
case etype2: printf("etype2 Error treated here\n");break;
default: printf("a type Error treated here\n");break;
}
}
}
void DerivedFirst(int k)
{ try {ThrowHandler(k);}
//catch(B b){b.HandleError();} //警告'class D' : is caught by base class ('class B ')
catch(D d) {d.HandleError();} //間接派生類對象數(shù)值形參catch塊置于前面
catch(C c) {c.HandleError();} //直接派生類對象數(shù)值形參catch塊置于中間
catch(B b) {b.HandleError();} //基類對象數(shù)值形參catch塊置于最后
catch(int ) { printf("a int Error treated here\n"); }
}
void main()
{ ////VirtualHandling(etype2+7);輸出結(jié)果a type Error treated here
VirtualHandling(classd); DerivedFirst(classc);
}
318
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -