「易碎基類問題」:頭文件變更會觸發所有包含它的源文件重新編譯。對於大型專案,編譯時間極其可觀。句柄類模式配合「不完整類型聲明」可大幅削弱此耦合。
類別 B 包裝類別 A(句柄類),A 定義在頭文件中。修改 A 的成員會導致 B 的頭文件變更,進而觸發所有使用 B 的文件重編。
// head.h
struct A { int i; }; // 完整定義
class B {
A* a; // 需要 A 完整定義
public:
B(int n = 0);
void show();
~B();
};
// head.h
class B {
struct A; // 不完整類型聲明(前向聲明)
A* a; // 僅需知道 A 是類型,指針大小固定
public:
B(int n = 0);
void show();
~B();
};
// head.cpp
#include "head.h"
#include <iostream>
struct B::A { // A 的完整定義下沉至實現文件
int i;
};
B::B(int n) {
a = new A;
a->i = n;
}
void B::show() { std::cout << a->i; }
B::~B() { delete a; }
A 的成員(增刪欄位、改型別)只需改動 head.cpp。head.h 不變 → 包含它的 main.cpp 等無需重新編譯。B::A 完整定義。| 場景 | 是否適用 |
|---|---|
| 大型專案、頻繁變更的內部實現類 | ✅ 極佳 |
| 小型專案、穩定介面 | ⚠️ 過度設計 |
| 需內聯/模板化的高頻調用 | ❌ 不適用(定義需在頭文件) |
此技巧屬於「編譯防火牆」模式核心手段之一,配合 Pimpl 慣用語可構建極具擴展性的 C++ 架構。