写在前面的话:
也忘了在哪里看到的这一句话:类就像是墙,把对象给保护起来啦,但是友元就像是墙上的一道门。这样做增加了程序的灵活性,但是同时也增加了风险性,所以要谨慎使用。 在C++中,我们使用类对数据进行了隐藏和封装,类的数据成员一般都定义为私有成员,成员函数一般都定义为公有的,以此提供类与外界的通讯接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。
友元函数:
友元函数不是类的成员函数,但是却写在类的声明中,只是前面要加上friend关键字。友元函数可以像成员函数一样调用类的所以成员。
注意:由于友元函数不是成员函数,所以没有this指针,所以友元函数的形参一般是对象。(也可以是静态成员)
代码示例:
#include <iostream>
using namespace std;
class Box
{
double width;
public:
friend void printWidth( Box box );
void setWidth( double wid );
};
// 成员函数定义
void Box::setWidth( double wid )
{
width = wid;
}
// 请注意:printWidth() 不是任何类的成员函数,形参为一个对象
void printWidth( Box box )
{
/* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */
cout << "Width of box : " << box.width <<endl;
}
// 程序的主函数
int main( )
{
Box box;
// 使用成员函数设置宽度
box.setWidth(10.0);
// 使用友元函数输出宽度
printWidth( box );
return 0;
}
友元类
class B{
public:
friend class A;
}
如上,A是B的友元类。那么A中的成员函数都是B的友元函数,也就是A中的所有成员函数都可以访问B的所有成员。
代码示例:
#include <iostream>
using namespace std;
class Box
{
double width;
public:
friend class A; //class A是class Box的友元类
void setWidth( double wid );
};
// 成员函数定义
void Box::setWidth( double wid )
{
width = wid;
}
class A{
public:
void printWidth( Box box )
{
/* 因为A 是 Box 的友元,A的成员函数可以直接访问该类的任何成员 */
cout << "Width of box : " << box.width <<endl;
}
};
// 程序的主函数
int main( )
{
Box box;
A a;
// 使用成员函数设置宽度
box.setWidth(10.0);
// 使用友元类输出宽度
a.printWidth( box );
return 0;
}
注意事项:
(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明