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

来源:互联网 发布:大数据产业园规划 编辑:程序博客网 时间:2024/05/21 09:44
/*条款31:将文件间的编译依存关系降到最低*/#include<iostream>#include<string>//如果不加上下面三行会编译不过,然而这就是形成编译依存关系的源头#include"data.h"#include"address.h"using namespace std;class Person {public:/*namespace std{ 但这是不正确,而是一个basic_string<char>的typedefclass string;}所以你的接口设计应该避免标准程序库中的#include那部分class Date;class Address;//前置声明编译器必须需要声明的原因在于它先要分配内存,而前提是必须知道对象的大小,内置类型倒也无所谓*/Person(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 the Address;};//--------------所以可以将对象实现细目隐藏于一个指针背后#include<string>//s标准库组件不该被前置声明#include<memory>class PersonImpl;//Person实现类的前置声明class Date;   //Person接口用到的类的前置声明class Address;class Person {public:Person(const string &name, const Date&birthday, const Address&addr) {}string name()const;string birthDate()const;string address()const;private:std::str1::shared_ptr<PersonImpl>pImpl;//指向实现物//这样Person的客户就完全与Date Address以及Persons的实现细目分离了//实现了接口与实现分离//这里的关键在于声明的依存性替换了定义的依存性,这正是编译依存最小化的本质/*设计策略:1 如果使用obj ref或obj ptr可以未完成任务,就不要使用obj  但如果定义obj 就需要用到定义式了2 如果能,尽量以类声明式替换类定义式  当你声明一个函数用到某个类,你不需要定义,给个前置声明  值传递也一样3 为声明式和定义式提供不同的头文件*/};//-----Person两个成员函数的实现#include "Person.h"//实现person 必须包含它的定义式#include"personImpl.h"//必须包含它的定义式,否则无法调用它的成员函数 personImpl有着和person完全相同的成员函数,两者接口完成相同Person::Person(const。。。) :pIml(new PersonImpl(name, birday, addr)) {}std::string Person name()const {return pImpl->name();}std::string Person::name()const {return Pimpl->name();}//--另一个制作Handle class 的办法 是让person成为抽象基类,称为接口类//它的目的是一一描述子类的接口,它通常不带成员变量,也没有构造函数,只有虚析构以及一组纯虚函数,用来 叙述整个接口class Person {public:virtual ~Person();virtual std::string name()const = 0;virtual std::string birthDate()const = 0;virtual std::string address()const = 0;//..static std::tr1::shared_ptr<Person> create(const std::string&name, const Date&birthday, const Address&addr);};class RealPerson :public Person {public://..对应具体接口规格的实现};//Handle classes interface classes 解除了接口与实现之间的耦合关系,从而降低了文件间的编译依存性//Handle类的受动态内存分配与释放而来的额外开销,interface类的virtual的开销这些带来的影响要于耦合带来的影响做一个权衡// 程序库头文件应以完全且仅有声明式的形式存在,这种做法不论是否涉及模板都适用int main() {share_ptr<Person>pp(Person::create(name, dateofBirth, address));cout << pp->name() << "was born on" << pp->birthDate() << "adnd now lives at" << pp->address();//...system("pause");return 0;}

0 0
原创粉丝点击