条款31:将文件间的编译依存关系降低至最低
- 如果使用object references或object pointers可以完成任务,就不要使用objects。你可以只靠一个类型声明式子就定义出指向该类型的1references和pointers;但如果定义式某类型的objects,就需要用到该类型的定义式。
- 如果能够,尽量以class声明式替换class定义式。注意,当你声明一个函数而它用到某个calss时,你并不需要该class的定义;纵使函数以by value方式传递该类型的参数(或返回值)也是一样的:
class Date; //class声明式。
Date today(); //没问题--这里并不需要
void clearAppointments(Date d); //Date的定义式
- 为声明式和定义式提供不同的头文件。为了促进严守上述准则,需要两个头文件,一个用于声明式,一个用于定义式.当然,这些文件必须保持一致性,如果有个声明式,被改变了,两个文件都得改变。因此程序库客户应该总是#include一个声明文件而非前置声明若干函数,程序库作者也应该提供这两个头文件。举个例子,Date的客户如果希望声明today和clearAppointments,他们不该像先前那样以手工方式前置声明Date,而是应该#include适当的、内含声明式的头文件:
#inclde "datefwd.h" //这个头文件内声明class Date
Date today(); //同前
void clearAppointments(Date d);
只含声明式的那个头文件名为“datefwh.h”,其对应定义则分布在若干不同的头文件,包括iostream,fstream等。
C++也提供关键字export,允许将template声明式和template定义式分割于不同的文件内。不幸的是支持这个关键字的编译器目前非常少,因此现实中使用这个关键字的经验也非常少。
请记住
- 支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式。基于此构想的两个手段是Handles classes和Interface classes。
- 程序库头文件应该以“完全且仅由声明式”的形式存在。这种做法不论是否涉及templates都适用。
条款32: 确定你的public继承塑膜出is-a关系
以C++进行面向对象编程,最重要的一个规则是:public inherittance(公开继承)意味“is-a”(是一种)的关系。
is-a并非是唯一存在于classes之间的关系。另两个常见的关系has-a(有一个)和is-implemented-in-terms-of(根据某物实现出)。这些关系将在条款38和39讨论。
请记住
- “public继承”意味is-a。适用于base classes身上的每一件事情一定也适用于derived classes身上,因为每一个derived class对象也都是一个base class对象。