友元函数和友元类

2015/05/30 C和C++基础

如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在类体中用friend对其进行声明,此函数就称为本类的友元函数。友元函数可以访问这个类中的私有成员

友元函数

1.将普通函数声明为友元函数
#include <iostream>
using namespace std;
class Time
{
public:
	Time(int,int,int);
	friend void display(Time &);   //声明display函数为Time类的友元函数
private:                           //以下数据是私有数据成员
	int hour;
	int minute;
	int sec;
};

Time::Time(int h,int m,int s){    //构造函数,给hour,minute,sec赋初值
	hour=h;
	minute=m;
	sec=s;
}

void display(Time& t){             //这是友元函数,形参t是Time类对象的引用,但是没有this指针
	cout<<t.hour<<":"<<t.minute<<":"<<t.sec<<endl;
}

int main( )
{ 
	Time t1(10,13,56);
	display(t1);                  //调用display函数,实参t1是Time类对象
	system("pause");            
}

由于声明了display是Time类的friend函数,所以display函数可以引用Time中的私有成员hour,minute,sec。但注意在引用这些私有数据成员时,必须加上对象名,不能写成:

cout<<hour<<":"<<minute<<":"<<sec<<endl;

因为display函数不是Time类的成员函数,不能默认引用Time类的数据成员,必须指定要访问的对象。

2.友元成员函数

friend函数不仅可以是一般函数(非成员函数),而且可以是另一个类中的成员函数。

友元成员函数的简单应用:

#include <iostream>
using namespace std;

class Date;                 //对Date类的提前引用声明

class Time                  //定义Time类
{
public:
	Time(int,int,int);
	void display(Date &);   //display是成员函数,形参是Date类对象的引用
private:
	int hour;
	int minute;
	int sec;
};

class Date                              //声明Date类
{
public:
	Date(int,int,int);
	friend void Time::display(Date &);  //声明Time中的display函数为友元成员函数
private:
	int month;
	int day;
	int year;
};

Time::Time(int h,int m,int s)          //类Time的构造函数
{
	hour=h;
	minute=m;
	sec=s;
}

void Time::display(Date &d){           //display的作用是输出年、月、日和时、分、秒
	cout<<d.month<<"/"<<d.day<<"/"<<d.year<<endl; //引用Date类对象中的私有数据
	cout<<hour<<":"<<minute<<":"<<sec<<endl;      //引用本类对象中的私有数据
}

Date::Date(int m,int d,int y){         //类Date的构造函数
	month=m;
	day=d;
	year=y;
}

int main()
{
	Time t1(10,13,56);      //定义Time类对象t1
	Date d1(12,25,2004);    //定义Date类对象d1
	t1.display(d1);         //调用t1中的display函数,实参是Date类对象d1
	system("pause");
}
3.一个函数(包括普通函数和成员函数)可以被多个类声明为“朋友”

如此就可以引用多个类中的私有数据。

友元类

不仅可以将一个函数声明为一个类的“朋友”,而且可以将一个类(例如B类)声明为另一个类(例如A类)的“朋友”。这时B类就是A类的友元类。友元类B中的所有函数都是A类的友元函数,可以访问A类中的所有成员。在A类的定义体中用以下语句声明B类为其友元类:

friend B;

声明友元类的一般形式为:

friend 类名;

关于友元,有两点需要说明:

(1)友元的关系是单向的而不是双向的。

(2)友元的关系不能传递。

在实际工作中,除非确有必要,一般并不把整个类声明为友元类,而只将确实有需要的成员函数声明为友元函数,这样更安全一些。关于友元利弊的分析:

面向对象程序设计的一个基本原则是封装性和信息隐蔽,而友元却可以访问其他类中的私有成员,不能不说这是对封装原则的一个小的破坏。但是它能有助于数据共享,能提高程序的效率,在使用友元时,要注意到它的副作用,不要过多地使用友元,只有在使用它能使程序精炼,并能大大提高程序的效率时才用友元。

Search

    Post Directory