- 最前面加上关键字 friend
- 友元是单向的,不具有交换性
- 实现互访需要两个类都将对方声明为自己的友元类
- 友元关系不具备传递性
- 使用友元可以避免频繁调用类的接口函数,提高效率,节省开销
3种形式
- 友元函数:不属于任何类的普通函数
- 友元成员:其他类的成员函数
- 友元类:另一个类
友元函数
- 通常友元函数是在类的定义中给出原型声明,声明位置不受访问属性限制
- 不同的属性但结果一样的
友元成员
- 向前声明
- 仅是类型说明符
- 只能用于定义引用和指针
- 不能用于定义对象
代码示例
#include<iostream> #include<iomanip> using namespace std; class Score; class Croster { private: string name; public: Croster(string na = "undef"); void PrintReport(const Score& s)const; }; class Score { private: int math, english; double GPA; public: Score(int x = 0, int y = 0); friend void Croster::PrintReport(const Score& s)const; }; Croster::Croster(string na) :name(na) {} Score::Score(int x, int y) :math(x), english(y) { GPA = (math + english) / 200.0 * 5; } void Croster::PrintReport(const Score& s) const { cout << "Name: " << name << endl; cout << "GPA: " << setprecision(2) << s.GPA << endl; cout << "Math: " << s.math << endl; cout << "English: " << s.english << endl; } int main() { int i; Croster stu[3] = { Croster("Alice"), Croster("Bob"), Croster("Charlie") }; Score s[3] = { Score(90, 80), Score(85, 95), Score(70, 80) }; for (i = 0; i < 3; i++) stu[i].PrintReport(s[i]); return 0; }
友元类
- 若 A 被声明为 B 的友元
- A 中的所有成员函数都是 B 类的友元成员,都可以访问 B 类的所有成员
代码示例
#include<iostream> #include<iomanip> using namespace std; class Croster; //向前声明 class CDate { private: int Date_year, Date_month, Date_day; public: CDate(int y=2000, int m=1, int d=1); friend Croster; }; class Croster { private: string name; double GPA; public: Croster(string n="undef", double G=3); void PrintInfo(const CDate& date) const; }; Croster::Croster(string n, double G):name(n), GPA(G) {} void Croster::PrintInfo(const CDate &date) const { cout << "Name: " << name << endl; cout << "GPA: " << fixed << setprecision(2) << GPA << endl; cout << "Date: " << date.Date_year << "-" << date.Date_month << "-" << date.Date_day << endl; } CDate::CDate(int y, int m, int d):Date_year(y), Date_month(m), Date_day(d) {} int main() { Croster stu("Tom", 3.8); CDate date(2019, 12, 10); stu.PrintInfo(date); return 0; }