兩個類互相引用:Screen 需要將 Window_mgr::clear 聲明為友元,Window_mgr 包含 vector 成員。若在頭文件中直接 #include 對方,會導致編譯順序問題:Screen.h 包含 Window_mgr.h,後者又包含 Screen.h,展開後 Window_mgr 定義在 Screen 使用之後,報錯「未定義」。
// Screen.h
#ifndef SCREEN_H
#define SCREEN_H
#include "Window_mgr.h" // 展開後 Window_mgr 尚未定義
class Screen {
friend void Window_mgr::clear(); // 錯誤:Window_mgr 不完整
...
};
#endif
// Window_mgr.h
#ifndef WINDOW_MGR_H
#define WINDOW_MGR_H
#include "Screen.h"
class Window_mgr {
void clear();
vector screens;
};
#endif
在 Screen.h 中**不包含** Window_mgr.h,僅前置聲明 class Window_mgr;。友元聲明只需要類名完整,不需要類定義完整。Window_mgr.h 正常包含 Screen.h(因需要知道 Screen 完整定義以實例化 vector)。
// Screen.h
#ifndef SCREEN_H
#define SCREEN_H
class Window_mgr; // 前置聲明
class Screen {
friend void Window_mgr::clear(); // 合法:只需類名
...
};
#endif
// Window_mgr.h
#ifndef WINDOW_MGR_H
#define WINDOW_MGR_H
#include "Screen.h" // 需要完整定義
class Window_mgr {
public:
void clear();
private:
vector screens; // 需要 Screen 完整類型
};
#endif
class X; 告訴編譯器 X 是一個類類型,允許聲明指針/引用/友元,但**不允許**實例化對象、訪問成員、繼承等需要知道大小/佈局的操作。vector 需要 Screen 完整定義(構造/析構/大小),故 Window_mgr.h 必須 #include "Screen.h"。friend void Window_mgr::clear(); 僅需 Window_mgr 是完整類類型,不需其定義體,前置聲明足夠。#include。#pragma once 或傳統宏防重複包含。.cpp 中包含所有需要的頭文件。