采用类的机制后实现了数据的隐藏与封装,只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,需要频繁地访问类的数据成员,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。这时可以将这些函数定义为该函数的友元函数。友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend。除了友元函数外,还有友元类,两者统称为友元。
(1)友元函数
友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样。如:
class CPoint
{
public:
CPoint();
CPoint(double _x, double _y){ x = _x; y=_y;}
friend double calcDistance(CPoint& pt1, CPoint& pt2);
private:
double x;
double y;
};
double calcDistance(CPoint& pt1, CPoint& pt2)
{
double dx = pt1.x - pt2.x;
double dy = pt1.x - pt2.x;
return sqrt(dx*dx+dy*dy);
}
int main(int argc, char* argv[])
{
CPoint pt1(3.0, 4.0);
CPoint pt2(4.0, 8.0);
double dist = calcDistance(pt1, pt2);
cout<<"calcDistance(pt1, pt2)="<<dist<<endl;
getchar();
return 1;
}
说明:在该程序中的CPoint类中说明了一个友元函数calcDistance(),它在说明时前边加friend关键字,标识它不是成员函数,而是友元函数。它的定义方法与普通函数定义一样,而不同于成员函数的定义,因为它不需要指出所属的类。但是,它可以引用类中的私有成员,函数体中pt1.x,pt2.x,pt1.y,pt2.y都是类的私有成员,它们是通过对象引用的。在调用友元函数时,也是同普通函数的调用一样,不要像成员函数那样调用。
(2)友元类
友元除了前面讲过的函数以外,友元还可以是类,即一个类可以作另一个类的友元。当一个类作为另一个类的友元时,这就意味着这个类的所有成员函数都是另一个类的友元函数。
在感情生活中,我们经常会遇到一些霸道的对象说:你的就是我的,我的就是我的(need is word ,word is still word)!,你有多少异性朋友,不能private,你银行卡的密码、QQ密码需要不能private,。。。。,即使private了,也要让我知道。呵呵,当然,对于一些大爱无私的男的,也总会满足自己女友的一些霸道条款。为了说明友元类,看下例:
class CBoyFriend
{
public:
CBoyFriend():girl_number(10),qq_password("123456789"){}
friend class CGirlFriend;
private:
int howManyGirlFriends(){ return girl_number;}
string whenToBuyRoses(){ return string("everyNight");}
private:
string bank_card;
string bank_card_password;
string qq_id;
string qq_password;
int girl_number;
};
class CGirlFriend
{
public:
CGirlFriend(){};
CBoyFriend boy;
void printBoyFriend()
{
cout<<"bank_card:"<<boy.bank_card<<endl;
cout<<"password:"<<boy.bank_card_password<<endl;
cout<<"qq_id:"<<boy.qq_id<<endl;
cout<<"qq_password:"<<boy.qq_password<<endl;
}
};
int main(int argc, char* argv[])
{
CGirlFriend girl;
girl.printBoyFriend();
getchar();
return 1;
}
根据类规则,private的成员变量和成员函数外面类是不能访问的,但是这里类CGirlFriend安排了一个friend间谍在CBoyFriend类内,就可以监视CBoyFriend的一切,随时可以查看其银行密码、QQ和QQ密码等。
使用友元类应注意:
(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元。
参考资料:
作者:kezunhai出处:http://blog.csdn.net/kezunhai欢迎转载或分享,但请务必声明文章出处。