<pre name="code" class="cpp"> lxImplement.h文件內容:
#include "lxTest.h"
class ClxImplement
{
public:
ClxImplement();
~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();
}
接口類:
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()
{
if (m_pImpl)
delete m_pImpl;
}
void ClxExp::DoSomething()
{
m_pImpl->DoSomething();
}
但是,如果類ClxExp是另一個類的子類,而在類ClxExp中要調用基類的方法,那上面的方案就不行了。比如說,類ClxExp的基類是下面的樣子:
class ClxInF
{
public:
ClxInF();
virtual ~ClxInF();
bool InitSet();
virtual void DoSomething();
};
相應的類ClxExp的聲明變成了如下的形式:
class ClxExp : public ClxInF
{
public:
ClxExp();
virtual ~ClxExp();
void DoSomething();
private:
ClxImplement *m_pImpl;
};
現在, 假設我們必須在類ClxExp的DoSomething()方法中根據InitSet()的返回值來確定是否執行操作。最簡單的實現方法是把類ClxExp的DoSomething()方法改成下面的樣子:
void ClxExp::DoSomething()
{
if (InitSet())
m_pImpl->DoSomething();
}
可是如果這樣的話,接口與實現就沒有徹底的分離,因爲實現細節被暴露到了接口類中。爲了避免這種情況發生,我們就必須把對基類ClxInF的方法InitSet()調用放到執行類ClxImplement當中。可是怎麼在執行類ClxImplement當中調用接口類ClxExp的基類ClxInF的方法呢?其實很簡單,因爲類ClxExp是類ClxInF的子類,那麼它也就繼承了類ClxInF的方法,只要把類ClxExp的this指針傳給類ClxImplement,就可以通過這個指針來調用類ClxExp的方法,當然也可以調用類ClxExp從基類ClxInF繼承來的方法。下面是修改後的代碼:
lxImplement.h文件內容:
#include "lxTest.h"
// 包含聲明類ClxExp的頭文件
#include "lxExp.h"
class ClxImplement
{
public:
// 構造函數,傳入類的ClxExp的指針
ClxImplement(ClxExp *plxExp);
~ClxImplement();
void DoSomething();
private:
ClxTest m_lxTest;
// 定義一個類ClxExp的指針,可以通過該指針調用類ClxExp從基類繼承下來的方法
ClxExp *m_plxExp;
void lxTest();
};
lxImplement.cpp文件內容:
#include "lxImplement.h"
ClxImplement::ClxImplement(ClxExp *plxExp)
{
m_plxExp = plxExp;
}
ClxImplement::~ClxImplement()
{
}
void ClxImplement::lxTest()
{
m_lxTest.DoSomething();
}
void ClxImplement::DoSomething()
{
if (m_plxExp->InitSet())
lxTest();
}
對於類ClxExp來說,只要修改一下它的構造函數就行了,其他都不用修改。
ClxExp::ClxExp()
{
m_pImpl = new ClxImplement(this);
}
這樣,我們就解決了前面所提到的問題。
當然,也許有人會說,讓類ClxImplement也從類ClxInF繼承不是更簡單嗎?那樣就可以在類ClxImplement中直接調用類ClxInF的方法,也不用添加什麼代碼。可是我們知道公有繼承是的子類與基類是IS-A的關係。也就是說子類是一種基類,就像說轎車是一種汽車一樣。可是,在我們例子中,類ClxImplement只是類ClxExp的一個執行類而已,跟類ClxExp的基類ClxInF沒有一點兒關係,更不要說是一種ClxInF了。所以不能讓類ClxImplement從類ClxInF繼承。
C++中接口與實現的分離技術
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.