您的位置:首页 > 其它

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

2015-09-17 03:42 375 查看
/*条款31:将文件间的编译依存关系降到最低*/
#include<iostream>
#include<string>//如果不加上下面三行会编译不过,然而这就是形成编译依存关系的源头
#include"data.h"
#include"address.h"
using namespace std;
class Person {
public:
/*
namespace std{ 但这是不正确,而是一个basic_string<char>的typedef
class 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: