当前位置:天才代写 > tutorial > C语言/C++ 教程 > C++中接口与实现疏散的技能

C++中接口与实现疏散的技能

2017-11-06 08:00 星期一 所属: C语言/C++ 教程 浏览:363

副标题#e#

在用C++写要导出类的库时,我们常常只想袒露接口,而埋没类的实现细节。也就是说我们提供的头文件里只提供要袒露的民众成员函数的声明,类的其他所有信息都不会在这个头文件内里显示出来。这个时候就要用到接口与实现疏散的技能。

下面用一个最简朴的例子来说明。

类ClxExp是我们要导出的类,个中有一个私有成员变量是ClxTest类的工具,各个文件内容如下:

lxTest.h文件内容:

class ClxTest
{
 public:
  ClxTest();
  virtual ~ClxTest();
  void DoSomething();
};

lxTest.cpp文件内容:

#include "lxTest.h"
#include <iostream>
using namespace std;
ClxTest::ClxTest()
{}
ClxTest::~ClxTest()
{}
void ClxTest::DoSomething()
{
 cout << "Do something in class ClxTest!" << endl;
}
////////////////////////////////////////////////////////////////////////////

lxExp.h文件内容:

#include "lxTest.h"
class ClxExp
{
 public:
  ClxExp();
  virtual ~ClxExp();
  void DoSomething();
 private:
  ClxTest m_lxTest;
  void lxTest();
};

lxExp.cpp文件内容:

#include "lxExp.h"
ClxExp::ClxExp()
{}
ClxExp::~ClxExp()
{}
// 其实该要领在这里并没有须要,我这样只是为了说明挪用干系
void ClxExp::lxTest()
{
 m_lxTest.DoSomething();
}
void ClxExp::DoSomething()
{
 lxTest();
}

为了让用户能利用我们的类ClxExp,我们必需提供lxExp.h文件,这样类ClxExp的私有成员也袒露给用户了。并且,仅仅提供lxExp.h文件是不足的,因为lxExp.h文件include了lxTest.h文件,在这种环境下,我们还要提供lxTest.h文件。那样ClxExp类的实现细节就全袒露给用户了。别的,当我们对类ClxTest做了修改(如添加或删除一些成员变量或要领)时,我们还要给用户更新lxTest.h文件,而这个文件是跟接口无关的。假如类ClxExp内里有许多像m_lxTest那样的工具的话,我们就要给用户提供N个像lxTest.h那样的头文件,并且个中任何一个类有窜改,我们都要给用户更新头文件。尚有一点就是用户在这种环境下必需举办从头编译!


#p#副标题#e#

上面长短常小的一个例子,从头编译的时间可以忽略不计。可是,假如类ClxExp被用户大量利用的话,那么在一个大项目中,从头编译的时候我们就有时间可以去喝杯咖啡什么的了。虽然上面的各种环境不是我们想看到的!你也可以想像一下用户在本身措施不消窜改的环境下要不断的更新头文件和编译时,他们心里会骂些什么。其实对用户来说,他们只体贴类ClxExp的接口DoSomething()要领。那我们怎么才气只袒露类ClxExp的DoSomething()要领而不又发生上面所说的那些问题呢?谜底就是--接口与实现的疏散。我可以让类ClxExp界说接口,而把实现放在别的一个类内里。下面是详细的要领:

首先,添加一个实现类ClxImplement来实现ClxExp的所有成果。留意:类ClxImplement有着跟类ClxExp一样的公有成员函数,因为他们的接口要完全一致。

lxImplement.h文件内容:

#include "lxTest.h"
class ClxImplement
{
 public:
  ClxImplement();
  virtual ~ClxImplement();
  void DoSomething();
 
 private:
  ClxTest m_lxTest;
  void lxTest();
};

lxImplement.cpp文件内容:

#include "lxImplement.h"
ClxImplement::ClxImplement()
{}
ClxImplement::~ClxImplement()
{}
void ClxImplement::lxTest()
{
 m_lxTest.DoSomething();
}
void ClxImplement::DoSomething()
{
 lxTest();
}

然后,修改类ClxExp。

修改后的lxExp.h文件内容:

// 前置声明
class ClxImplement;
class ClxExp
{
 public:
  ClxExp();
  virtual ~ClxExp();
  void DoSomething();
 private:
  // 声明一个类ClxImplement的指针,不需要知道类ClxImplement的界说
  ClxImplement *m_pImpl;
};

修改后的lxExp.cpp文件内容:

// 在这里包括类ClxImplement的界说头文件
#include "lxImplement.h"
ClxExp::ClxExp()
{
 m_pImpl = new ClxImplement;
}
ClxExp::~ClxExp()
{
 delete m_pImpl;
}
void ClxExp::DoSomething()
{
 m_pImpl->DoSomething();
}

通过上面的要领就实现了类ClxExp的接口与实现的疏散。请留意两个文件中的注释。类ClxExp内里声明的只是接口罢了,而真正的实现细节被埋没到了类ClxImplement内里。为了能在类ClxExp中利用类ClxImplement而不include头文件lxImplement.h,就必需有前置声明class ClxImplement,并且只能利用指向类ClxImplement工具的指针,不然就不能通过编译。

#p#分页标题#e#

在宣布库文件的时候,我们只需给用户提供一个头文件lxExp.h就行了,不会袒露类ClxExp的任何实现细节。并且我们对类ClxTest的任何窜改,都不需要再给用户更新头文件(虽然,库文件是要更新的,可是这种环境下用户也不消从头编译!)。这样做尚有一个长处就是,可以在阐明阶段由系统阐明员可能高级措施员来先把类的接口界说好,甚至可以把接口代码写好(譬喻上面修改后的lxExp.h文件和lxExp.cpp文件),而把类的详细实现交给其他措施员开拓。

 

    关键字:

天才代写-代写联系方式