将文件之间的编译依赖关系降至最低

考虑这样几个类,A、a1、a2、B,其中A和B是要暴露给用户的类。

 

1.最初组织关系如下:

 //a1.h

#include <iostream>

class a1
{
public:
 void DoSomething()
 {
   std::cout<<"a1 do sth"<<std::endl;
 }
};

 

//a2.h

#include <iostream>

class a2
{
public:
 void DoSomething()
 {
  std::cout<<"a2 do sth"<<std::endl;
 }
};

 

//B.h

#include <iostream>

class B
{
public:
 void DoSomething()
 {
   std::cout<<"B do sth"<<std::endl;
 }
};

 

//A.h

#include "a1.h"
#include "a2.h"
#include "B.h"

class A
{
public:
 void DoSomething(); 

 B ReturnB(); 
private:
 a1 _a1;
 a2 _a2;
};

 

//A.cpp

#include "A.h"

void A::DoSomething()
{
 _a1.DoSomething();
 _a2.DoSomething();
}

B A::ReturnB()
{
 return B();
}

 

//user.cpp

#include "A.h"

 

int main()
{
 A a;
 a.DoSomething();
 a.ReturnB().DoSomething();
}

 

因此,user.cpp 中直接或间接的include了A.h B.h a1.h a2.h,而且user根本不知道已经include了 这么多.h,尤其是不知道已经include了B.h。因此,如果与接口无关类型a1.h和a2.h改变了,会导致user.cpp重新编译。

 

2.利用指针/引用进行实现之:

a1.h a2.h B.h不用更改。

//A.h

class a1;
class a2;

class B;

class A
{
public:
 void DoSomething(); 

 B ReturnB(); 
private:
 a1 *_a1;
 a2 *_a2;
};

 

//A.cpp

#include "A.h"
#include "a1.h"
#include "a2.h"
#include "B.h"

void A::DoSomething()
{
 _a1 = new a1();
 _a1->DoSomething();
 delete _a1;

 _a2 = new a2();
 _a2->DoSomething();
 delete _a2;
}

B A::ReturnB()
{
 return B();
}

 

//user.cpp

#include "A.h"
#include "B.h"//显示指明我要你

 

int main()
{
 A a;
 a.DoSomething();
 B b = a.ReturnB();b.DoSomething();
}

//此时user.cpp只是包含了A.h 和 B.h,因此a1.h和a2.h修改的时候,user.cpp不用再重新编译。但是user可以看到A.h里含有a1,a2这些毫无意义的东西,这样的话,是暴露了其内部实现,因此我们纳入一个新的类AImpl来消灭这个暴露狂。

 

3.实现AImpl,将A变成一个Handle class

a1.h a2.h B.h不变。

//AImpl.h  //真是臃肿,懒得写AImpl.cpp了

#include "a1.h"
#include "a2.h"
#include "B.h"

class AImpl
{
public:
 void DoSomething()
 {
  _a1.DoSomething();
  _a2.DoSomething();
 }

 B ReturnB()
 {
  return B();
 }
private:
 a1 _a1;
 a2 _a2;
};

 

//A.h

class AImpl;

class B;

class A
{
public:
 void DoSomething(); 

 B ReturnB(); 
private:
 AImpl *aImpl;
};

 

//A.cpp

#include "A.h"

#include "AImpl.h"

#include "B.h"

void A::DoSomething()
{
 aImpl->DoSomething();
}

B A::ReturnB()
{
 return aImpl->ReturnB();
}

 

//user.cpp不变,但是这次他看到的A.h就没有_a1和_a2这些东西了~~~~

 

以上这类方法叫做Handle class,不过我怎么觉得没什么大用啊,c++标准库里有应用吗?谁知道,麻烦告诉小弟声~~~

另外Effective C++里还有另外一种方法,叫做Protocal class,相貌如下:

class AProtocal
{
 A *makeA();
 void DoSomething();
 B ReturnB();
}

所以实现也就不言自明了,另外比较高级的实现方法,就是将A public继承一个接口类,并private 继承一个实现类,具体见书本吧。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值