1、为什么要引入友元函数:
类具有封装性和隐蔽性,只有类的成员函数才能访问类的私有成员,程序中的其他函数式无法访问类的私有成员。但是,有些时候,要求程序设计者必须确保每个类都能够提供足够的成员函数对所有可能遇到的访问请求进行处理(即有可能去访问其他类的私有成员)。并且,由于某些成员函数的频繁调用,由于函数参数的传递、C++严格的类型检查和安全性检查都将带来时间上的开销,从而影响程序的运行效率。
但是,如果将类的成员访问控制属性设计成public类型,这样类的非成员函数就可以访问类的成员,如此一来就破坏了类封装性和隐蔽性,失去了C++最基本的优点。
友元不是类的成员,但是他可以访问类的任何成员,声明为友元的外界对象既可以是一个类的成员函数,又可以是不属于任何类的一般函数,称之为友元函数。
在实现类之间数据共享时,减少系统开销,提高效率
具体来说:为了使其他类的成员函数直接访问该类的私有变量
即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一成员优点:能够提高效率,表达简单、清晰
缺点:友元函数破环了封装机制,尽量不使用友元函数,除非不得已的情况下才使用友元函数。
类具有封装和信息隐藏的特性,只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类的公有成员。
友元是一种定义在类外部的普通函数,但是需要在类中进行说明,为了与其他的成员函数加以区别,在说明时要加上关键字friend,友元不是成员函数,但是它可以访问类中的私有成员,友元的作用在于提高程序的运行效率,但是破坏了类的封装性和隐藏性,使得非成员函数也可以访问类的私有成员
2、什么时候使用友元函数:
1)运算符重载的某些场合需要使用友元。
2)两个类要共享数据的时候
3、怎么使用友元函数:
友元函数的参数:
因为友元函数没有this指针,则参数要有三种情况:
1、 要访问非static成员时,需要对象做参数;--常用(友元函数常含有参数)
2、 要访问static成员或全局变量时,则不需要对象做参数
3、 如果做参数的对象是全局对象,则不需要对象做参数
友元函数的位置:
因为友元函数是类外的函数,所以它的声明可以放在类的私有段或公有段且没有区别。
友元函数可以在类内声明,在类外定义,但是在类外定义的时候不得指出函数所属的类。
友元函数的调用:
可以直接调用友元函数,不需要通过对象或指针。
友元函数不是一个普通的函数,他不是类的成员函数,因此在调用的时候不能通过对象调用。
成员友元函数
#include
//1:函数原型给出形参的默认值的时候,形参名可以省略。
//2: 友元函数类内声明,类外定义 返回类型 函数名(形参表) 不能给出类属性
//但是在这种情况下 是需要给出类属性的 一个类在使用另一个类的函数 good
//3: this-> 类结束要打上;号 返回类型 所属类::函数名(形参表)
//4: 还有就是类的提前引用声明
using namespace std;
class Date;//对Date类的提前引用声明
class Time
{
private :
int hour;
int minute;
int second;
public :
Time(int=11,int=23,int=44);
void call(Date &);
};
class Date
{
private :
int year;
int month;
int day;
public :
Date(int=2013,int=10,int=4);
friend void Time::call(Date &);//表明我使用的是Time里面的函数作为我的friend函数
//可以使次函数具有访问我私有变量能力。
};
Time::Time(int hour,int minute,int second)
{
this->hour = hour;
this->minute = minute;
this->second = second;
}
Date::Date(int year,int month,int day)
{
this->year = year;
this->month = month;
this->day = day;
}
void Time::call(Date &d)
{
cout<<"time is "<
全局友元函数
#include
using namespace std;
//1:函数原型给出形参的默认值的时候,形参名可以省略。
//2: 友元函数类内声明,类外定义 返回类型 函数名(形参表) 不能给出类属性
//3: this-> 类结束要打上;号 返回类型 所属类::函数名(形参表)
class Time
{
private:
int hour;
int minute;
int second;
public:
Time(int=11,int=21,int=31);
friend void call(Time &);
};
Time ::Time(int hour,int minute,int second)
{
this->hour = hour;
this->minute = minute;
this->second = second;
}
void call(Time &t)
{
cout<<"time is "<