尽可能延后变量定义式的出现时间
尽量少做转型动作
避免返回handles指向对象内部成分
为“异常安全”而努力是值得的
透彻了解inlining的里里外外
将文件间的编译依存关系降至最低
本章主要考虑在实现类功能编码时要注意的点,包括实现优化、异常安全处理。
写精简的程序
精简程序即缩衣节食、物尽其用,减少资源使用的小原则:
- 尽可能延后变量定义时间;
这里不得不也说说资源初始化:
bool init()
{
// 资源声明
...
// 资源创建1,出错返回
... {
return false;
}
// 资源创建2,出错返回
... {
return false;
}
...
return true; // 正常返回
}
这里带来的隐藏问题很多:
- 对于多个资源需要创建的情况,出错时能否安全退出?
- 创建某个资源失败时,之前创建的资源能否及时销毁?
- 销毁已创建资源的重复代码如何减少?
一种被广泛接受的结构:
bool init()
{
// 资源声明
bool error = false;
do {
// 资源创建1,出错跳出
... {
error = true;
break;
}
// 资源创建2,出错跳出
... {
error = true;
break;
}
...
} while(false);
if (error) {
// 已创建资源检查销毁
...
}
return (!error);
}
此种结构有效解决了创建失败及时退出问题和销毁资源的代码共用问题。当然,资源声明时该调用的构造函数在这里丝毫没有节省,但似乎这里更偏向结构的精简和资源的安全。在这个内存以 G
起步的时代,作者所述这些微小的优化其实也并不是那么必要,而由于结构设计不善导致的浪费会远远大于这些。
写安全的程序
转型安全:
区别C++提供四种新式转型:
const_cast<T>(expression)
:去除const对象的常量性;dynamic_cast<T>(expression)
:安全向下转型,例如基类指针转子类指针时使用,转换失败会返回null;reinterpret_cast<T>(expression)
:低级转型,实际结果取决于编译器(貌似并不常用);static_cast<T>(expression)
:强迫隐式转换,例如non-const转为const;int转为double等。但不支持const转为non-const,这只能使用const_cast
。
dynamic_cast
和 static_cast
是比较类似的,但在向下转型时会有明显区别:dynamic_cast
支持向下转型,转型失败时会返回null;而使用 static_cast
向下转型通常不会完全成功,失败时也不会返回null(即不是转型安全的)。
返回安全:
尽量少返回对象内部的 指针、引用和迭代器 ,因为外部对其的操作会直接影响对象,除非有意为之。
异常安全:
异常安全函数即使发生异常也不会泄漏资源或允许任何数据结构败坏。这样的函数区分为三种可能的保证:基本型、强烈型、不抛异常型。
写低耦合的程序
透彻了解inlining的里里外外
放哪里呢?就塞这吧…
低耦合的目标是:让代码改动波及的范围最小化,一些原则:
- 接口和实现分开:这里Java做的相当好,另外一些开源库,例如Irrichit等也体现的相当明显;
- 声明与实现分开:使用单独头文件去声明。
耦合度与开始时的结构设计是直接相关的,so,编码前不如先做好结构规划。