C++中接口与实现分离的技术

2016-02-19 18:07 29 1 收藏

最近很多朋友喜欢上设计,但是大家却不知道如何去做,别担心有图老师给你解答,史上最全最棒的详细解说让你一看就懂。

【 tulaoshi.com - 编程语言 】


  在用C++写要导出类的库时,我们经常只想暴露接口,而隐藏类的实现细节。也就是说我们提供的头文件里只提供要暴露的公共成员函数的声明,类的其他所有信息都不会在这个头文件里面显示出来。这个时候就要用到接口与实现分离的技术。
  
  下面用一个最简单的例子来说明。
  
   类ClxEXP是我们要导出的类,其中有一个私有成员变量是ClxTest类的对象,各个文件内容如下:
  
   lxTest.h文件内容:  
  
  class ClxTest
  
  {
  
  public:
  
  ClxTest();
  
  virtual ~ClxTest();  
  
  void DoSomething();
  
  };  
  
   lxTest.cpp文件内容:  
  
  #include "lxTest.h"  
  
  #include
  
  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那样的头文件,而且其中任何一个类有改动,我们都要给用户更新头文件。还有一点就是用户在这种情况下必须进行重新编译!上面是非常小的一个例子,重新编译的时间可以忽略不计。但是,假如类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对象的指针,否则就不能通过编译。在发布库文件的时候,我们只需给用户提供一个头文件lxExp.h就行了,不会暴露类ClxExp的任何实现细节。而且我们对类ClxTest的任何改动,都不需要再给用户更新头文件(当然,库文件是要更新的,但是这种情况下用户也不用重新编译!)。这样做还有一个好处就是,可以在分析阶段由系统分析员或者高级程序员来先把类的接口定义好,甚至可以把接口代码写好(例如上面修改后的lxExp.h文件和lxExp.cpp文件),而把类的具体实现交给其他程序员开发。
  
  原文地址:http://blog.csdn.net/starlee/archive/2006/02/27/610825.ASPx

来源:https://www.tulaoshi.com/n/20160219/1616849.html

延伸阅读
众所周知,Java语言最明显的优势在于用它设计的程序可以广泛地运行于互联网上所有安装了VM解释器的计算机上。然而,如今JAVA之所以在市场上如此流行,还得益于它的另一卖点:它提供了安全可靠和使用方便的存储治理机制。这是部分编程人员将它与其前身C++语言对比后所得出的结论。本文将针对两种语言的内存(以对象为单位)使用机制,...
问题 C语言以及C++语言中的const究竟表示什么?其具体的实现机制又是如何实现的呢? 本文将对这两个问题进行一些分析,简单解释const的含义以及实现机制。 问题分析 简单的说const在C语言中表示只读的变量,而在C++语言中表示常量。关于const在C与C++语言中的使用以及更多的区别,以后有时间另开一贴说明。 那么const究竟是如何实现的...
导言 多态(polymorphism)一词最初
我这篇文章的主旨是介绍一部分类和接口的高质量设计的准则。这些准则不但应该保证设计并且实现的类或者接口本身有高质量代码,而且更重要的是在工业领域应该尽可能的使代码的更新和维护不影响客户的活动,主要也就是保持二进制代码兼容(binary compatibility)和源代码兼容(source compatibility)。我希望这些准则能帮助刚从学校进入工业领...
在C++中,以类、虚函数等为代表的数据抽象功能一直是C++的核心和难点。这里我想结合自己的使用经验,谈谈对C++中抽象的一点浅薄看法! 我认为C++的抽象应该是指:从我们需要解决的问题出发,在与该问题相关的一组关联对象中提取出主要的或共有的部分――说简单一点,就是用相同的行为来操作不同的对象。 从提出问题到找出与该问题...

经验教程

342

收藏

82
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部