friend 允許特定非成員函數或類存取類的 private/protected 成員,打破封裝邊界。這是為了效率(避免存取函數開銷)或實現特定協作模式(如運算子多載、工廠模式)而設計的「後門」。
class A {
int id;
friend void display(const A& a); // 宣告
};
void display(const A& a) {
std::cout << a.id; // 直接存取 private 成員
}
A 的成員,無 this 指標。A::。A 所有成員,繞過類型檢查與存取控制。class A {
int id;
friend class B; // B 所有成員函數皆為 A 的友元
};
class B {
void showA(const A& a) { std::cout << a.id; }
};
B 的所有成員函數自動成為 A 的友元。A 不自動獲得 B 的存取權。class A; // 前向宣告
class B {
void showA(A& a);
};
class A {
int id;
friend void B::showA(A& a); // 僅授權特定成員函數
};
void B::showA(A& a) { std::cout << a.id; }
B 完整定義需在 A 友元宣告之前。| 特性 | 說明 |
|---|---|
| 宣告位置 | 類內部,不受 public/private/protected 影響 |
| 繼承性 | 不繼承:基類友元不自動成為派生類友元 |
| 傳遞性 | 無傳遞性:A 是 B 友元,B 是 C 友元 ⇒ A 非 C 友元 |
| 雙向性 | 單向:A 授權 B 存取 A,不代表 B 授權 A 存取 B |
operator<<、operator>>、operator== 等需存取私有成員的非成員函數。protected 介面。std::optional/std::variant 替代部分友元用途。getter/setter 配合 [[nodiscard]]、constexpr 等屬性,編譯器內聯優化可消除開銷。friend 是 C++ 傳遞「信任」的機制,如同現實生活中的後門:有時必要(消防通道),但濫用會導致安全隱患。理解其語義、範圍與替代方案,在效能與封裝間取得平衡,是成熟 C++ 開發者的必修課。