友元
友元的内容:
- 引入友元
- 友元的分类
- 友元函数
- 友元类
- 友元的优缺点
- 友元的注意事项
一、引入友元
一个常规的成员函数(不是static、const修饰的,不是友元的)声明描述了三件在逻辑上相互不同的事情:
- 该函数能访问类声明的私有部分。
- 该函数位于类的作用域之中。
- 该函数必须经由一个隐藏的this指针去调用。
通过该函数声明为static,可以让它只有前两种性质。因为static修饰的函数无this指针。
通过将一个函数声明为友元可以使它只具有第一种性质。因为友元函数不属于类的成员函数。
- 友元是一种说明在类体外非成员函数,友元不是成员函数,但它可以访问类中的私有成员。
- 友元的作用在于提高程序的运行效率,但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类中的私有成员。
二、友元分为:友元函数和友元类
友元函数
- 友元函数可以直接访问类的私有成员。
- 它是定义在类外部的普通函数,不属于任何类。
- 但需要在类的内部声明,声明时需加 friend 关键字。
//友元函数
class Date
{
//友元函数在类内部声明
friend void PrintDate(Date d);
public:
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{}
private:
int _year;
int _month;
int _day;
};
//在类体外定义
void PrintDate(Date d)
{
cout << d._year << "-" << d._month << "-" << d._day << endl;
}
int main()
{
Date d(2018, 5, 1);
PrintDate(d);
return 0;
}
友元函数须注意:
- 友元函数可以访问类的私有成员,但它不是类的成员函数。
- 友元函数不用const修饰。
- 友元函数可以在类定义的任何地方声明,不受类访问限定符限制,但不能放在成员函数里面去。
- 一个函数可以是多个类的友元函数。
- 友元函数的调用与普通函数的调用和原理相同。
友元类
友元类即是一个类可以作为另一个类的友元,意味着这个类的所有成员函数可以是另一个类的友元函数,都可以访问另一类的非公有成员。
//友元类
class Date; // 因为Data类定义在Time类后面,所以得先声明Data类
class Time
{
//Date类中的成员可以访问Time类的私有部分
friend class Date;
public:
Time(int hour, int minute, int second)
: _hour(hour)
, _minute(minute)
, _second(second)
{}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{}
void SetDate(int hour)
{
t._hour = hour;
}
private:
int _year;
int _month;
int _day;
Time t;
};
int main()
{
Date d(2018, 5, 1);
Time t(12, 12, 12);
return 0;
}
三、友元的优缺点:
- 优点:提高了程序运行的效率。
- 缺点:破坏了类的封装性和隐藏性。
四、友元须注意:
- 友元关系不能继承
- 友元关系不能传递。
- 友元关系是单向的,不具有交换性。