開發庫時,我們希望只公開介面 (公有成員函式),隱藏實現細節 (私有成員、輔助類別)。但若公開類別 ClxExp 直接包含另一類別 ClxTest 的物件作為成員,頭文件就必須 #include "lxTest.h"。後果是:
ClxTest 任何修改 (增減成員) 都需發布新頭文件,使用者被迫重新編譯。核心思想:公開類別僅保留一個指向實現類別的指標,實現細節完全移至另一類別,頭文件只需前置宣告。
// 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(); }
// lxExp.h (發布給使用者)
class ClxImplement; // 前置宣告
class ClxExp {
public:
ClxExp();
virtual ~ClxExp();
void DoSomething();
private:
ClxImplement* m_pImpl; // 僅持有指標,無需知道定義
};
// lxExp.cpp (內部實現,不發布)
#include "lxImplement.h"
ClxExp::ClxExp() : m_pImpl(new ClxImplement) {}
ClxExp::~ClxExp() { delete m_pImpl; }
void ClxExp::DoSomething() { m_pImpl->DoSomething(); }
lxExp.h,完全看不到 ClxTest、ClxImplement 細節。lxExp.h/cpp),實現細節交由其他工程師開發。Pimpl 是大型 C++ 專案控制編譯依賴、維護二進位相容性的基石技術。