友元提供了不同类的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。通过友元,一个不同函数或者另一个类中的成员函数可以访问类中的私有成员和保护成员。C++中的友元为封装这堵墙开了一个小孔,外界可以通过这个小孔窥视内部的秘密。
友元的正确使用可以提高程序的运行效率,但同时也破坏了类的封装性和数据的隐藏性,导致程序可维护性变差。
友元函数
友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend
,其格式如下:
friend <类型> <函数名>(形参);
友元函数的声明可以放在类的私有部分,也可以放在公有部分,他妈说没有区别的,都说明时该类的一个友元函数。
友元函数的调用与一般函数的调用方式和原理一致。
友元类
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。
当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:
friend class <类名>
其中
friend
和class
是关键字,类名必须是程序中一个已经定义过的类。
例如,一下语句说明类B是类A的友元类:
class A
{
…
public:
friend class B;
…
};
类B的所有成员函数都是类A的友元函数,能存取类A的私有成员和保护成员。
使用友元类时注意:
- 友元关系不能被继承。
- 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
- 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明
示例
友元函数showN访问private变量
#include <iostream>
using namespace std;
class Internet
{
public:
Internet(char *name,char *address) // 改为:internet(const char *name , const char *address)
{
strcpy(Internet::name,name);
strcpy(Internet::address,address);
}
friend void ShowN(Internet &obj); //友元函数的声明
private:
char name[20];
char address[20];
};
void ShowN(Internet &obj) //类外普通函数定义,访问a对象的保护成员name,不能写成,void Internet::ShowN(Internet &obj)
{
cout<<obj.name<<endl; //可访问internet类中的成员
}
void main()
{
Internet a("谷歌","http://www.google.cn/";);
ShowN(a);
cin.get();
}
友元类A访问类B的private变量
分别定义一个类A和类B ,各有一个私有整数成员变量通过构造函数初始化;类A有一个成员函数Show(B &b)用来打印A和B的私有成员变量,请分别通过友元函数和友元类来实现此功能。
使用友元类和友元函数实现:
#include <iostream>
using namespace std;
class B;
class A;
void Show( A& , B& );
class B
{
private:
int tt;
friend class A;
friend void Show( A& , B& );
public:
B( int temp = 100):tt ( temp ){}
};
class A
{
private:
int value;
friend void Show( A& , B& );
public:
A(int temp = 200 ):value ( temp ){}
void Show( B &b )
{
cout << value << endl;
cout << b.tt << endl;
}
};
void Show( A& a, B& b )
{
cout << a.value << endl;
cout << b .tt << endl;
}
int main()
{
A a;
B b;
a.Show( b );
Show( a, b );
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!