C++笔记(4)用于大型程序的工具

4.1 异常处理

 

try

{

//throw ; 函数暂停执行,查找catch.

}

catch ()

{

         /*执行catch之后,在紧接在try相关的最后一个catch子句之后的代码点继续运行*/

}

catch ()

{

}

try 代码块中抛出异常, 寻找最近的catch,如果当前函数中没有找到,则寻找上一层调用函数直至寻找到匹配的catch,否则调用teminate()函数,终止程序.

 

在处理异常的时候会释放局部存储,所以被抛出的对象就不能再局部存储,而是用throw表达式初始化一个异常对象(抛出对象的副本),异常对象由编译器管理,而且保证驻留在可能被激活的任意catch都可以访问的控件,在完全处理后撤销,所以抛出的异常对象必须是可以赋值的类型.

 

异常对象是抛出对象的副本, 所以如果抛出指针的解引用,则指针指向的对象如果动态绑定, 都抛出指针指向类型(基类部分,继承类被分割).

 

析构函数不应该抛出异常

如果在析构函数中发生异常,则改对象可能只是部分被构造,部分成员还未被初始化.

 

4.2 重新抛出

 

throw;

catch中处理了异常, 如果仍然希望此异常传递, 调用throw;重新抛出异常, 如果catch形参为引用,则抛出改变后的异常,否则抛出原异常.

 

chtch(…) 捕获所有异常.一般为最后一个catch.

 

用类管理资源分配,代替new,delete, 避免在new之后发生异常而无法delete.

class resource

{

public:

         resource(parms p): r(alloocate(p)){...}

         ~resource(){release(r);}

private:

         resource_type *r;

         resource_type* allocate(parms p);

         void release(resource_type *);

}

 

4.3 auto_ptr

 

atuo_ptr<T> ap(p); //p为指向对象的指针.

ap1 = ap2; /*删除ap1ap2指向的对象, ap1指向ap2原指向的对象, ap2成为未绑定的.所以不能将auto_ptr对象存储在标准容器中,标准容器类要求赋值或复制之后两个对象相等. */

~ap; //析构ap所指向的对象

*ap; //返回对ap所绑定的对象的引用

ap->; //返回ap所保存的指针

ap.reset(p); //如果app的值不同,则删除ap所指向的对象并将p所指向的对象绑定到ap.

ap.release; //返回ap所保存的指针, ap成为为绑定的.

ap.get(); //返回ap所保存的指针.

 

auto _ptr<int> ap(new int(1));

auto _ptr<int> ap(new int[2]); /*error,auto_ptr只能用于管理从new返回的一个对象,而不能管理动态分配的数组,它使用的是delete,而不是delete[] */

不要用 auto_ptr指向静态分配对象的指针,否则,auto_ptr对象本身被撤销的时候,它将试图删除指向非动态分配对象的指针,导致未定义行为.

不要使用两个auto_ptr指向同一对象.

 

void func(void); //可以抛出任何异常.

void func(void) throw(); //承诺不抛出任何异常

void func(void) throw(runtime_error); /*如果func抛出异常,则异常是runtime_error对象,如果抛出其他异常,则调用unexpected, unexpected调用teminate(). */

 

派生类虚函数的异常说明必须与对应基类函数的异常说明同样严格或者比后者更受限,不可增加新的可抛出异常.

 

void(*pf)(int) throw(runtime_error); //函数指针pf形参为int, 返回void, 可能抛出runtime_error. 而函数指针指向的函数的异常说明必须与指针异常相同或者更严格.

原文地址:https://www.cnblogs.com/zengyou/p/2195588.html