經典難題:類 A 以**值**成員持有 B,類 B 以**指針**持有 A。直接包含頭文件會導致遞歸定義編譯錯誤。解決鍵在於:**前向聲明 + 指針/引用成員 + 實現文件中包含完整定義**。
// A.h
class B; // 前向聲明
class A {
B* b_ptr; // 指針/引用不需要完整定義
public:
void setB(B* b) { b_ptr = b; }
void callB();
};
// B.h
class A; // 前向聲明
class B {
A* a_ptr;
public:
void setA(A* a) { a_ptr = a; }
void callA();
};
// A.cpp
#include "A.h"
#include "B.h" // 此處需要 B 完整定義
void A::callB() { if (b_ptr) b_ptr->callA(); }
// B.cpp
#include "B.h"
#include "A.h" // 此處需要 A 完整定義
void B::callA() { if (a_ptr) a_ptr->callB(); }
// main.cpp
#include "A.h"
#include "B.h"
int main() {
A a; B b;
a.setB(&b); b.setA(&a);
a.callB(); // 相互調用
}
class B;,成員只能是 **指針/引用** (B*/B&),**不可為值類型** (B b; 需完整定義知大小)CTestDlg (對話框類) 持有 A 對象,A 需回調 CTestDlg 方法。
步驟:
A.h 前向聲明 class CTestDlg;,成員 CTestDlg* m_pDlg;A.cpp 包含 "TestDlg.h" 實現回調CTestDlg.h 包含 "A.h",成員 A m_a; (值類型,需完整定義)CTestDlg.cpp 構造時 m_a.setDlg(this);Test.h → A.h → TestDlg.h (避免循環包含)std::unique_ptr / std::shared_ptr 管理生命週期,同樣只需前向聲明A 持有 IB*,B 繼承 IB