正常如果声明一个类,会在头文件中写它的成员函数和成员变量。问题就是发生在这,成员函数是接口,而成员变量是实现。将其混在头文件中会有问题。假设我们更改了类的成员变量(实现),理论上接口没变,那么只用重新编译链接这个类就好了。但是因为两者混在头文件,导致整个项目都要重新编译链接。另一方面,客户可以通过头文件去看到部分实现,也违背了封装性的原则。Handle Class技术便是针对这一问题而生的,先看看它的代码结构://Object类的.h文件#include <memory>classObjectImpl;classTime;className;classObject{public: Object(const Name& name,const Time* time); ~Object(); const Name& getName() const; const Time& getTime() const;private: //指向实现类的指针 std::tr1::shared_ptr<ObjectImpl> pImpl;};
//Object类的.cpp文件#include"object.h"#include<iostream>// 实现类class ObjectImpl {public: ObjectImpl(const Name& name,const Time* time); ~ObjectImpl(); const Name& getName()const; const Time& getTime()const;private: Time time; Name name;};//定义实现类的成员函数(包含完整逻辑)...//定义Object类的成员函数(调用ObjectImpl)...
Handle Class技术的做法是将声明和实现分为两个类,声明类只有接口和一个指向实现类的指针,实现类则负责具体实现。如此,实现的改变便不会影响项目整体,并且用户也看不到具体的实现。- objectfwd.h:将前向声明集中,交给客户引用。
- object.h:包含完整的接口声明,引用objectfwd.h,交给客户引用。
- objectimpl.h:包含ObjectImpl的声明与部分实现,引用object.h,不提供给用户。
- object.cpp:包含Object和ObjectImpl的实现,引用objectimpl.h。