友元
一个类的私有成员为了某些保护上的意义一般是不能被访问的,但是在程序里有一些私有属性也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术。故友元的意义就是让一个函数或者类来访问类中的私有成员(其实既然私有成员可以访问,那类里的所有成员基本都可以访问)
友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用
友元函数
一个全局函数试图访问data类里的私有成员变量,自然不被允许
class date
{
public:
void test_pri(date* dt);
date(int year=1000,int month=1,int day=1)
:_year(year)
,_month(month)
,_day(day)
{}
private:
int _year;
int _month;
int _day;
};
void test_pri(date* dt)
{
dt->_year;
}
但是如果告诉类,该函数是我的朋友!(友元)
就可以编译通过:
class date
{
public:
friend void test_pri(date* dt);
//void test_pri(date* dt);
date(int year=1000,int month=1,int day=1)
:_year(year)
,_month(month)
,_day(day)
{}
private:
int _year;
int _month;
int _day;
};
void test_pri(date* dt)
{
dt->_year;
}
友元函数可访问类的私有和保护成员,但不是类的成员函数
友元函数不能用const修饰
友元函数可以在类定义的任何地方声明,不受类访问限定符限制
一个函数可以是多个类的友元函数
友元函数的调用与普通函数的调用和原理相同
友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员
class 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;
// 友元类
friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量
};
class Date
{
public:
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;
};
要注意的是:
友元关系是单向的,不具有交换性
意思是date类中可以直接访问time类的私有成员变量,但是time类是不可以访问date类的私有成员变量
此外,如果B是A的友元,C是B的友元,则不能说明C时A的友元,友元并没有传递性。