假设你对 C++ 程序的某个 class 实现文件做了些轻微改变,修改的不是接口,而是实现,而且只改 private 成分。
然后重新建置这个程序,并预计只花数秒就好,当按下 “Build” 或键入 make,会大吃一惊,因为你意识到整个世界都被重新编译和链接了!
问题是在 C++ 并没有把 “将接口从实现中分离” 做得很好。class 的定义式不只详细叙述了 class 接口,还包括十足的实现细目:
class PersonEx{
public:
PersonEx(const std::string& name, const Date& birthday, const Address& addr);
std::string name() const;
std::string birthDate() const;
std::string address() const;
...
private:
std::string theName;
Date theBirthDate;
Address theAddress;
};
这个 class Person 无法通过编译,Person 定义文件的最上方可能存在这样的东西:
#include <string>
#include "date.h"
#include "address.h"
这样一来,便在 Person 定义文件和其含入文件之间形成了一种编译依存关系(compilation dependency)。如果这些头文件中有任何一个被改变,或这些文件所依赖的其他头文件有任何改变,那么每个含入 Person class 的文件就得重新编译,任何使用 Person class 的文件也必须重新编译。这样的的连串编译依存关系(cascading compilation dependencies)会对许多项目造成难以形容的灾难。
下面给出一种方法:
如果能够,尽量以 class 声明式替换 class 定义式。
当你声明一个函数而它用到某个 class 时,你并不需要该 class 的定义式,纵使函数以 by value 方式传递该类型的参数(或返回值)亦然。
下面是PersonEx;  实现: 
PersonExImpl:  实现; 
Date:  实现:  Address:  实现: 
Main:  将Person的构造函数多加一行空格: 添加之前:  添加之后:   
|