采用类的机制后实现了数据的隐藏与封装,只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,需要频繁地访问类的数据成员,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。这时可以将这些函数定义为该函数的友元函数。友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字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欢迎转载或分享,但请务必声明文章出处。