都是非常好的东西,非大型程序用了也很好啊
发生异常时,当前函数如果没有catch,则会发生栈展开,分配的局部对象会销毁释放析构.所以利用RAII释放资源是安全的(线程被意外终止不会执行栈展开,TerminateThread)
构造函数中发生异常,当前的对象可能只构造了一部分,即使某个对象只构造了一部分,我们也于要确保一构造的成员能被正确地销毁.类似的,异常也可能发生在数组或标准容器的元素初始化过程中,可能已经构造了一部分元素,则我们应该确保这部分元素被正确的销毁(怎么保证销毁?)
析构函数被执行时有可能发生异常,则不择释放资源的代码有可能被跳过,我们要确保无论析构函数正常还是遭遇异常,资源都能被正确释放.
我们应该确保析构函数不会对外释放异常.
异常对象必须拥有可访问的拷贝或移动构造函数和析构函数,编译器使用一场对象进行拷贝初始化,异常对象位于百年一起管理的空间中,编译器确保无论最终调用的是哪个catch都能访问该空间,当异常处理完毕后,一场对象被销毁.主要不要抛出局部对象的指针或引用,因为栈展开,局部对象已经不存在了
重新抛出,仅有一个throw语句, throw;只有当catch为引用类型是,修改过的异常对象,被重新抛出,才会被修改.
捕获所有异常使用 catch(...){}
构造函数抛出异常,因为在初始值列表抛出异常时,构造函数体内的try语句块还为生效,所以如果想处理构造函数初始化列表中抛出的异常,必须将构造函数写成函数try语句块,既能处理构造函数题,也能处理构造函数初始化过程.try出现在参数列表后面,构造函数初始化列表冒号(:)前面,catch出现在函数体后面
int Base(int a) try : b(a){}catch{}
如果在初始化构造函数参数时发生异常,则该异常属于调用表达式的一部分.
noexcept,指定某个函数不会抛出异常.等价于throw()声明(测试了一下,貌似没什么区别,加不加都一样)
命名空间别名
namespace pri = std;
虚继承.虚基类由最底层的派生类初始化.虚基类总是先于非虚类构造