把资源封装在对象内,通常可以在exception出现时避免资源泄露
C++仅仅能删除被完全构造的对象(fully constructed objects),只有一个对象的构造函数完全运行完毕,这个对象才被完全地构造。C++拒绝为没有完成构造操作的对象调用析构函数。
在构造函数中可以使用try catch throw捕获所有的异常。更好的解决方法是通过智能指针的方式。
如果你用对应的std::unique_ptr或者shared_ptr对象替代指针成员变量,就可以防止构造函数在存在异常时发生资源泄漏,你也不用手工在析构函数中释放资源,并且你还能像以前使用非const指针一样使用const指针,给其赋值。
1.可以避免terminate函数在exception传过程的栈展开机制中被调用。
如果控制权基于exception的因素离开destructor,而此时正有另一个exception处于作用状态,C++会调用terminate函数结束程序
2.可以协助确保destructor完成其所应该完成的所有事。
如果exception从destructor内抛出,而且没有在当地被捕获,destructor便是执行不全,仅执行到异常抛出那一点。
函数参数和exception的传递方式有三种:by value,by reference,by pointer
catch by reference可以避免by pointer的对象删除问题,也可以避开by value的切割问题(派生类exception 对象被捕捉并被视为基类异常者,将失去派生成分,切割了子类可能需要的虚函数功能)。
一个程序80%的资源用域20%的代码,80%的执行时间花费在20%的代码上。
以某种方式撰写classes,使它们延缓计算,直到那些运算结果刻不容缓被迫切需要为止。可应用于:Reference Counting(引用计数)来避免非必要的对象复制、区分 operator[] 的读和写动作来做不同的事情、Lazy Fetching(缓式取出)来避免非必要的数据库读取动作、Lazy Expression Evaluation(表达式缓评估)来避免非必要的数值计算动作。
和上一条款相反,要求超前进度的做要求以外的更多工作。
Over-eager evaluation:如果你预期你的程序常常会用到某个计算,你可以设计一份数据结构一边能够有效率的处理需求。
例如常用的caching缓存技术。
第二种是prefetching预先取出,比如stl种vecctor动态内存的分配,当需要扩张时,每次分配2倍内存。
有时候某些操作或者函数必然要返回对象,就要产生临时对象,这无法避免,比如operator*,如果一定得以by-value方式返回对象,可以以一种特殊写法撰写函数,让他返回constructor arguments以取代对象。
此特殊的优化行为——利用函数的return点消除一个局部临时对象。
称为Return value optimization。
如下:
注意:每个“重载操作符”必须获得至少一个用户自定义类信息的自变量。所以最后一个重载操作是错的。