引言
与主流观点相反,从根本上说,最普通形式的面向对象程序要比对应的面向过程的程序更难测试和校验。通过虚函数改变内部行为的能力可能导致类不变式无效;而对于程序的正确性来说,类不变式是必要的。
第一部分 基础知识
对符号名称的使用,而不是声明本身,导致一个未定义符号被引入到.o目标文件中。
typedef声明是的性质属于"internal linkage",尽管这个说法不严谨,但是很容易理解──文件A无法使用文件B中typedef的类型。
C++中不可能未经定义就声明一个枚举类型,即对于class合法的foward declation,并不适用于enum。
typedef只是提供了”创建新类型“的假象。
类之间的逻辑关系:每一种都暗示着两个逻辑实体之间不同程度的物理依赖
IsA
Uses-In-The-Interface
Uses-In-The-Implementation
继承和分层是逻辑层次结构的两种表现形式
分层:较高抽象层次的类依赖较低抽象层次的类(人依赖于脑、胃,可以理解为组合)
继承:具体的类依赖抽象的类
避免在头文件的file scope中使用枚举、typedef和常量数据;它们都默认为internal linkage。更好的方法是将他们放入头文件的class scope中。
头文件的"外部冗余#include guard"
理论上将,头文件的"内部 #include guard"就足够了,但是对于大型项目,事情并不这么简单
对于具有高密度头文件包含图的大型项目,在每个头文件中的每个#include指令周围,加上一个冗余的”外部#include guard“,对于降低编译时间,能起到显著作用。
注意,对于.cpp文件, 外部 冗余#include guard并不是必需的。
第二部分 物理设计概念
第三章、组件
3.1 组件和类
从纯粹的逻辑角度看,一个设计可以看作是类和函数的海洋,那里没有物理分区存在──每一个类和自由函数都驻留在一个单一的无缝空间内。
组件 (component)是物理设计的最小单位。
组件不是类,反之亦然。一个组件一般包括一个或多个相关的类,以及和类相关的非成员函数。
在结构上,组件是一个不可分隔的物理单位。一个组件严格的由一个头文件和一个实现文件组成。
组件的逻辑接口:客户可通过编程访问或检测到的东西
组件的物理接口:头文件中的所有东西
从逻辑角度看,组件的实现文件中有或没有使用什么都是封装的细节,并不重要;从物理角度看,这样的使用可能隐含着对其它组件的物理依赖。在大型系统中这些物理依赖会影响可维护性和可重用性。
3.2 物理设计规则
1.在一个组件内部声明的逻辑实体,不应该在该组件之外定义(类声明除外)。
2.组成一个组件的.cpp和.h的文件名应该严格匹配
3.每个组件的.cpp文件应该将#include其对应头文件作为其代码的第一行有效语句,这样每个组件可以确保它自己的头文件对于编译来说都是自我满足的,组件的头文件中不会 遗漏 组件物理接口的关键信息──如果有的话,在编译组件时就会发现错误。
4.