一般函式無法存取類別的 protected/private 成員。若全部設為 public,又會暴露給所有外部程式碼。friend 關鍵字允許指定函式/類別存取私有成員,在保護資料安全與提供必要存取間取得平衡。但會破壞封裝性,現代 C++ 建議慎用,優先考慮公開介面設計。
class Internet {
public:
Internet(char* name, char* addr) { strcpy(name_, name); strcpy(addr_, addr); }
friend void ShowN(Internet& obj); // 宣告友元函式
private:
char name_[20];
char addr_[20];
};
void ShowN(Internet& obj) { // 定義時不加 Internet::
cout << obj.name_ << endl;
}
void main() {
Internet a("Lab", "www.lab.com");
ShowN(a); // 正常呼叫
}
注意:友元函式 不是 類別成員,定義時不可寫成 void Internet::ShowN(...)。
class Country; // 前向宣告
class Internet {
friend void ShowN(Internet&, Country&); // 共同友元
// ...
};
class Country {
friend void ShowN(Internet&, Country&); // 同一函式為兩個類別的友元
// ...
};
void ShowN(Internet& i, Country& c) { /* 可存取兩者私有成員 */ }
class Internet; // 前向宣告
class Country {
public:
void EditUrl(Internet&); // 成員函式宣告
};
class Internet {
friend void Country::EditUrl(Internet&); // 指定成員函式為友元
// ...
};
void Country::EditUrl(Internet& t) { // 定義
strcpy(t.addr_, "new.address");
}
class Country {
friend class Internet; // 整個 Internet 類別皆為友元
// ...
};
class Internet {
public:
void EditCountryName(Country& c) { strcpy(c.name_, "New Name"); } // 可存取 Country 所有私有成員
};
友元類別的所有成員函式自動成為友元,可存取對方所有私有/受保護成員。
輸出運算子 operator<< 常宣告為友元,以便存取私有資料格式化輸出:
class Complex {
friend ostream& operator<<(ostream&, const Complex&);
// ...
};
Friend 提供受控的封裝突破,適用於運算子多載、緊密協作的類別組。濫用會導致維護困難,現代 C++ 偏好透過公開介面、Getter/Setter 或組合模式解決。