// ExceptionStudy.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> using namespace std; class CMyException { public: CMyException(void) { cout << "CMyException constructor" << endl; } CMyException(const CMyException& oth) { cout << "CMyException copy" << endl; } void Dispaly(void) { cout << "Display" << endl; } }; void TestFun(void); void TestFun(void) { //0 CMyException e; throw e; } /* 抛出的局部对象不能再局部存储,而是用throw表达式初始化为一个称为异常对象的特殊对象 异常对象由编译器管理,而且保证驻留在可能被激活的任意catch都可以访问 */ class CMyExceptionBase { public: CMyExceptionBase(void) { cout << "CMyExceptionBase constructor" << endl; } CMyExceptionBase(const CMyExceptionBase& oth) { cout << "CMyExceptionBase copy" << endl; } virtual void Display(void) { cout << "CMyExceptionBase Display" << endl; } }; class CMyExceptionDrive : public CMyExceptionBase { public: CMyExceptionDrive(void) { cout << "CMyExceptionDrive constructor" << endl; } CMyExceptionDrive(const CMyExceptionDrive& oth) { cout << "CMyExceptionDrive copy" << endl; } void Display(void) { cout << "CMyExceptionDrive Display" << endl; } }; void TestFun2(void); void TestFun2(void) { CMyExceptionDrive e; CMyExceptionBase* p = &e; throw *p; //对象切割,执行的是CMyExceptionBase拷贝构造函数构造异常对象 } //关于对象切割 class CObjBase { public: CObjBase(void) { cout << "CObjBase constructor" << endl; } CObjBase(const CObjBase& oth) { cout << "CObjBase copy" << endl; } virtual void fun1(void) { cout << "CObjBase fun1" << endl; } }; class CObjDrive : public CObjBase { public: CObjDrive(void) { cout << "CObjDrive constructor" << endl; } CObjDrive(const CObjDrive& oth) { cout << "CObjDrive copy" << endl; } void fun1(void) { cout << "CObjDrive fun1" << endl; } }; int _tmain(int argc, _TCHAR* argv[]) { //00 try { TestFun(); } catch (CMyException e) { e.Dispaly(); } /* CMyException constructor CMyException copy 被抛出表达式的副本 CMyException copy 值拷贝 Display 请按任意键继续. . . */ //01 try { TestFun(); } catch (CMyException& e) //直接引用异常对象 { e.Dispaly(); } /* CMyException constructor CMyException copy Display 请按任意键继续. . . */ cout << "222222222222222222222222222222222222222222222222222222222222222222" << endl; try { TestFun2(); } catch(CMyExceptionBase e) { e.Display(); } /* CMyExceptionBase constructor CMyExceptionDrive constructor CMyExceptionBase copy 被抛出表达式的副本(执行的是基类的拷贝构造函数)生成异常对象 CMyExceptionBase copy 没有引用,传值发生拷贝 CMyExceptionBase Display 请按任意键继续. . . */ cout << "33333333333333333333333333333333333333333333333333333333333333333333" << endl; CObjDrive obj; CObjBase* p = &obj; p->fun1(); obj.fun1(); ((CObjBase)obj).fun1(); //发送对象切割,实际调用基类拷贝构造函数构造一个临时对象 /* 基类的异常说明符可以用于捕获派生类型的异常对象 */ cout << "444444444444444444444444444444444444444444444444444444444" << endl; try { CMyExceptionDrive haha; throw haha; //先调用CMyExceptionDrive拷贝构造函数生成异常对象,对象切割调用CMyExceptionBase拷贝构造函数生成CMyExceptionBase对象 } catch(CMyExceptionBase e) { e.Display(); } /* CMyExceptionBase constructor CMyExceptionDrive constructor CMyExceptionBase constructor CMyExceptionDrive copy CMyExceptionBase copy CMyExceptionBase Display 请按任意键继续. . . */ return 0; } /* 注意 析构函数应该从不抛出异常(在为某个异常栈展开时,析构函数抛出自己的未处理的另一个异常将会导致调用标准库terminate函数) 构造函数中抛出异常要适当的撤销已经构造部分成员 */