条款 31 将文件间的编译依存关系降至最低

条款 31 : 将文件间的编译依存关系降至最低

Minimize compilation dependencies between files

C++没有把“将接口从实现中分离”这件事做得很好。Class的定义不止是叙述了类接口,还包括了十足的实现细节。

例如下面代码:

#include"Date"
#include<string>

class Person{
public:
    Person();
    std::string name()const;
    std::string date()const;
private:
    std::string theName;//实现细目
    Date BirDate;//实现细目
    
}

很不幸,上面的申明方式使得Person类的定义文件引入了其他文件,这就形成了一种编译依赖关系。任何其他文件的改变都将导致Person文件需要从新编译。

或许你会奇怪C++为什么坚持将class 的实现细目放在class定义式内,而不是用下述代码方式:

namespace std{class string;}//前置声明,错误
class Date;//前置声明

class Person{
public:
    Person();
    std::string name()const;
    std::string date()const;
    ...    
}

如果采用这种前置声明的方式,也就不存在编译依赖关系了。但是该方法是错误的。第一,string并不是一个class;第二,**“前置声明每一个东西”的困难是编译器必须在编译期间就知道对象的大小。**但是不将实现细目放进class内,编译器又从何得知呢。这种问题在Java中并不存在,因为其定义对象时只不过是给其分配了一个指针罢了。这是一个好的策略,也就是常说的pimpl策略。

Pimpl策略的关键在于用“声明的依存性”替换“定义的依存性”,这正是编译依赖性最小化的本质:实现中让头文件尽可能自我满足,如果做不到。则让他与其他文件内的声明式(而不是定义式)相互依存。即:

  1. 如果使用object reference或object pointer可以完成任务,就不要使用object.
  2. 如果可以,尽量以class声明替换class的定义。
  3. 为声明式和定义式提供不同的头文件。
  4. 还有一种方法就是定义Person为虚基类,也就是interface class。这样的类的功能类似Java中的Interface。

请记住

  1. 支持“编译依存性最小化”的一般构想是:相依于申明式,不要相依与定义式。基于此构想的两个手段是Handle class 和Interface class.
  2. 程序头文件应该以“完全且仅有声明式”(full and declaration only forms)的形式存在。这种方法无论是否涉及template都适用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值