C++—友元函数

来源:互联网 发布:网络推广学什么 编辑:程序博客网 时间:2024/06/08 20:00

                C++友元函数

友元函数是什么呢?顾名思义“友元”,朋友的元素,那么大家都可以共享啦,这也就是友元的作用。

在C++中友元函数允许在类外访问该类中的任何成员,就象成员函数一样,友元函数用关键字friend说明。

那么问题来了,为什么会需要友元函数和友元类呢??

类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问
私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏
的特性。另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和
安全性检查等都需要时间开销,而影响程序的运行效率。
  为了解决上述问题,提出一种使用友元的方案。友元是一种定义在类外部的普通函数,但它需要在类体
内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是
它可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,
使得非成员函数可以访问类的私有成员。
  友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。
  友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,
即在定义上和调用上与普通函数一样。
下面是我写的一个例子,分析一下友元函数~:

首先我定义了一个Date类,然后分别为它初始化私有成员年月日,我在类中重载一个“<<”运算符,我想让它
直接可以输出Date的私有成员(这里有一个小问题,在类中当你调用这个运算符时写法与平时不同有些别扭)
,所以我又在类外重载相同的运算符(这里定义时,就是平时使用cout<<d1的方式),然后通过使用友元函数
的概念在类外进行该类的友元函数的定义,这样在它的类外也可以使用类中的私有成员。

# define _CRT_SECURE_NO_WARNINGS 1#include<iostream>#include<windows.h>using namespace std;class Date{friend void Display(const Date& d);friend void operator<<(ostream& out, const Date& d);friend void operator>>(istream& in, Date& d);public:Date(int year, int month, int day){cout << "构造调用成功了" << endl;_year = year;_month = month;_day = day;}// 拷贝构造函数Date(const Date& d){cout << "拷贝构造被调用了" << endl;_year = d._year;_month = d._month;_day = d._day;}void operator<<(ostream& out){out << _year << "_" << _month << "_" << _day << endl;}private:int _year;int _month;int _day;};void Display(const Date& d){cout << d._year << " " << d._month << " " << d._day << endl;}void operator<<(ostream& out,const Date& d){out << d._year << "_" << d._month << "_" << d._day << endl;}void operator>>(istream& in, Date& d){in >> d._year;in >> d._month;in >> d._day;}int main(){Date d1(2017, 3, 6);d1 << cout;  //d1.operator<<(cout);等同于上式//上面就是在类中定义的函数cin >> d1;cout << d1;Display(d1);//这个是在类外定义的友元函数system("pause");return 0;}


看看运行的结果:


友元函数的调用就是在类外实现完毕,在类内往它声明之前加一个friend关键字声明,这样他就是一个合格
的友元函数,可以访问类内的所有成员,是不是很方便?

还有!!

我们刚刚发现在类中定义了一个运算符“<<”的重载,但是我们可以发现在类的内部调用他的方式略显
别扭“d1<<cout”,所谓为了解决这个问题,我们在类外调用一个友元函数,这样就可以将参数的位置调换
完美的解决了调用方式的问题,直接"cout<<d1",就可以直接使用。

还有友元类的使用:

整个类可以是另一个类的友元。友元类的每个成员函数都是另一个类的友元函数,都可访问另一个类中的保
护或私有数据成员。

class Time{     // Date是Time 的友元,所以 Date可以访问Time的所有成员。     friend class Date;private :     int _hour ;     int _minute ;     int _second ;};class Date{public :     void Display ()    {          cout<<"year:" <<_year<< endl;          cout<<"month:" <<_month<< endl;          cout<<"day:" <<_day<< endl;          // 定义为友元类后,可以访问Time类对象的所有成员          cout<<"hour:" <<_t. _hour<<endl ;          cout<<"minute:" <<_t. _minute<<endl ;          cout<<"second:" <<_t. _second<<endl <<endl;    }private :     int _year ;     // 年     int _month ;    // 月     int _day ;      // 日     Time _t ;};void Test (){     Date d1 ;     d1.Display ();}




不出所料,这里可以访问友元类的私有成员。

具体都是这样用的,但是呢友元一定程度上破坏了C++的封装,友元不宜多用,在恰当的地方使用友元。




0 0
原创粉丝点击