handle class和interface class

降低文件间的依存关系:
第一种方法: handle class
把一个类变为一个接口类和一个实现类 实现类就是原来的这个类,接口类就是原来这个类的接口函数(public)和 一个private的智能指针对象(一般为shared_ptr)指向实现类,接口类里面需要用到的类,我们提供给它的都是类的前向声明,所以为了严格执行这样的准则,我们把每一个类(包括接口类和实现类)都提供两个头文件,一个是类的声明 xxfwd.h 一个是类的定义 xx.h 


接口类的fwd.h   class xx fwd.;
接口类的头文件  include的都是 xxfwd.h   就是接口类需要用到的类的fwd.h 和实现类的 fwd.h
接口类的源文件  include 自己的头文件和实现类的头文件 接口函数的实现通过实现类的接口函数实现

实现类的fwd.h   class xximplfwd; 
实现类的头文件  include 用到的类的 接口类 的头文件 
实现类的源文件  include  实现类的头文件
 

// file : Person.h 原来的
#include <string>
#include "date.h"
#include "address.h"

class Person{
    public:
    Person( const std::string& name, const Date& birthday, const Address& addr );
    std::string name() const;
    std::string birthData() const;
    std::string address() const;
    ...
    private:
    std::string theName;
    Date theBirthDate;
    Address theAddress;
}

// Personfwd.h
class Person;

// datefwd.h
class date;

//Person.h
#include <string>
#include <memory.h>
#include "datefwd.h"
#include "addressfwd.h"
#include "PersonImplfwd.h"
class Person{
    public:
    Person( const std::string& name, const Date& birthday, const Address& addr );
    std::string name() const;
    std::string birthData() const;
    std::string address() const;
    ...
    private:
    std::shared_ptr<PersonImpl> pImpl; // 指针指向实现物
}

//PersonImpl.h  有着和Person完全相同的成员函数,两者接口完全相同。
#include "date.h"
#include "address.h"
class PersonImpl
{
    public:
    PersonImpl( const std::string& name, const Date& birthday, const Address& addr );
    std::string name() const;
    std::string birthData() const;
    std::string address() const;
    ...
    private:
    std::string theName;
    Date theBirthDate;
    Address theAddress;
}

//Person.cpp
#include "Person.h"
#include "PersonImpl.h"
std::string Person::name() const{
    return pImpl->name();
}
...
...

//PersonImpl.cpp
#include "PersonImpl.h"
std::string PersonImpl::name() const {
    return theName;
}
...
...

优点

  • Person.h 实现了与之前依赖的头文件 date.h 和 address.h 及由此递归依赖的文件的解耦,可是改为 PersonImpl.h依赖上述文件,只是该依赖不会继续向上传递;
  • Person 类型的声明 Person.h 及实现 PersonImpl.h 的解耦, 修改 Person 类实现时,只需要修改 PersonImpl.h 即可,不会影响使用 Person 类的文件。

代价

  • 成员函数必须通过 implemention pointer 取得对象数据,访问是间接的,且增加了 implemetion pointer 的指针的内存,增加了动态内存分配的管理开销,及 bad_alloc 异常的处理难度。

 

第二种方法: interface class 
原来一个A类,让它的接口成为一个抽象基类 class A,具体是 接口函数都定义成为 纯虚函数,  析构函数是虚函数,还有一个static工厂函数 create 返回shared_ptr<A> 
它的实现成为派生类  Aimpl,这样改变A类的实现,就改变Aimpl的实现就ok了
客户用的时候只能  shared_ptr<A>  Aptr(A::create(参数) ) ; 这样用



 

猜你喜欢

转载自blog.csdn.net/speargod/article/details/89005605