友元函数
class Date
{
public:
Date(int year, int month, int day)
:_year(year)
, _month(month)
, _day(day)
{
}
ostream& operator<<(ostream& _cout)
{
_cout << _year << "年" << _month << "月" << _day << "日";
return _cout;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d(2025, 8, 2);
d << cout << endl;//不符合常规调用
//cout<< d << endl;//正常书写
return 0;
}
当我们运行上述代码,可以正常对类进行打印,但代码的书写却不符合常规的调用,因此我们需要在类外面对这一函数进行定义,但是由于需要直接访问类的私有成员,因此这就需要用到友元函数。
友元函数是可以直接访问类中私有成员 的函数,它定义在类外且不属于任何类 ,但却需要在类内声明 ,声明时需要在函数返回类型前加关键字friend。
class Date
{
friend ostream& operator<<(ostream& _cout, const Date& d);//类内声明
friend istream& operator>>(istream& _cin, Date& d);
public:
Date(int year, int month, int day)
:_year(year)
, _month(month)
, _day(day)
{
}
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)//类外定义
{
_cout << d._year << "年" << d._month << "月" << d._day << "日";
return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{
_cin >> d._year >> d._month >> d._day;
return _cin;
}
int main()
{
Date d(2025, 8, 2);
cout << d << endl;
cin >> d;
cout << d << endl;
return 0;
}
注:友元函数可以访问类的私有成员和保护成员,但它不属于类
友元函数由于没有this指针,因此不能用const修饰
友元函数可以在类中任何地方声明,不受访问限定符的限制
一个函数可以是多个类的友元函数
友元函数的调用与普通函数的调用原理相同
友元类
友元类的所有成员函数都可以是另一个类的友元函数,且都可以访问另一个类中的非公有成员
友元关系是单向的,并不具有交换性
友元关系不能传递
友元关系不能继承
class Time
{
friend class Date; //声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有变量
public: //且友元是单向的,时间类无法访问日期类的私有成员
Time(int hour = 0, int minute = 0, int second = 0)
: _hour(hour)
, _minute(minute)
, _second(second)
{}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year)
, _month(month)
, _day(day)
{}
void SetTimeOfDate(int hour, int minute, int second)
{
// 直接访问时间类私有的成员变量
_t._hour = hour;
_t._minute = minute;
_t._second = second;
}
private:
int _year;
int _month;
int _day;
Time _t;
};