- 最前面加上关键字 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;
}