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

编译依存的问题——170

通常,我们的定义的文件包含很多头文件,这些文件和其含入文件之间形成了一种编译依存关系。如果这些头文件中有任何一个被改变,或这些头文件所依赖的其他头文件有任何改变,那么每一个含入我们定义的文件就得重新编译,任何使用我们定义的文件也必须重新编译。这样的连串编译依存关系会对许多项目造成难以形容的灾难。

使用指针指向类——172

我们可以将Person分割为两个calsses,一个只提供接口,另一个负责实现该接口:

#include<string>
#include<memory>

class PersonImpl;       //Person实现类的前置声明
class Date;               //Person接口用到的class的 前置声明
class address;

class Person{
public:
    Person(const std::string& name,const Date& birhday,const Address& addr);
    std::string name() const;
    std::string birthDate() const;
    std::string address() const;
    ...
private:
    std::tr1::shared_ptr<PersonImpl> pImpl;
};

在这里,main clss(Person)只内含一个指针成员,指向其实现类(PersonImpl)。这样的设计之下,Person的客户就完全与Dates,Address以及Persons的实现细目分离了。那些classes的任何实现修改都不需要Person客户端重新编译。
我们有如下设计策略:
(1)如果使用object references 或 object pointers可以完成任务,就不要使用objects。
(2)如果能够,尽量以class声明式替换class定义式。
(3)为声明式和定义式提供不同的头文件。

制作Handles classes的两种办法——174

第一种办法就如上节所述使用pimpl idiom的classes。这种办法是将它们所有函数转交给相应的实现类(implementation classes)并由后者完成实际工作。例如:

#inlcude "Person.h"
#inlcude "PersonImpl.h"         //PersonImpl有着和Person完全相同的成员函数,两者接口完全相同。
Person::Person(const std::string& name,const Date& birthday,const Address& addr)
    :pImpl(new PersonImpl(name,birthday,addr)) {}
std::string Person::name() const
{
    return pImpl->name();
}

第二种办法令Person成为一种特殊的抽象基类,称为Interface class。这种class通常不带成员变量,也没有构造函数,只有一个virtual析构函数以及一组pure virtual函数(C++ Primer 5th,540),用来叙述整个接口。一个针对Person而写的Interface class如下:

class Person{
public:
    virtual ~Person();(C++ Primer 5th,540)
    virtual std::string name() const=0;
    virtual std::string birthDate() const=0;
    virtual std::string address() const=0;
    ...
};

具体实现由客户定义。
不论Handle classes或Interface classes,一旦脱离inline函数都无法有太大作为。(条款30)

总结——178

(1)支持“编译依存性最小化”的一般构想是:相依于声明式,不要相依于定义式。基于此构想的两个手段是Handle classes和Interface classes。
(2)程序头文件应该以“完全且仅有声明式”的形式存在。这种做法不论是否涉及templates都适用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值