原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/
有些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问,这是很方便做到的。例如被重载的操作符,如输入或输出操作符,经常需要访问类的私有数据成员。
友元(frend)机制允许一个类将对其非公有成员的访问权授予指定的函数或者类,友元的声明以friend开始,它只能出现在类定义的内部,友元声明可以出现在类中的任何地方:
友元不是授予友元关系的那个类的成员,所以它们不受其声明出现部分的访问控制影响。通常,将友元声明成组地放在类定义的开始或结尾是个好主意。
1普通函数友元函数
友元函数是指某些虽然不是类成员函数却能够访问类的所有成员的函数。类授予它的友元特别的访问权,这样该友元函数就能访问到类中的所有成员。
目的:使普通函数能够访问类的友元
声明: friend + 普通函数声明
实现位置:可以在类外或类中
实现代码:与普通函数相同
调用:类似普通函数,直接调用
#include <iostream> using namespace std; class Atest { public: Atest() :value(20) {} ~Atest(){} private: friend void function(Atest&);//该函数是友元函数的声明 int value; static int sta_val; }; void function(Atest& test)//友元函数定义,为了访问类Atest中的成员 { cout <<"value is "<<test.value<<endl; cout <<"static is "<<Atest::sta_val<<endl; } int Atest::sta_val = 100; int main(int argc, char const *argv[]) { Atest struct_val; function(struct_val); return 0; }
執行結果:
2类Y的所有成员函数都为类X友元函数—友元类
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。
关于友元类的注意事项:
(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明。
目的:使用单个声明使Y类的所有函数成为类X的友元,它提供一种类之间合作的一种方式,使类Y的对象可以具有类X和类Y的功能。
声明位置:公有私有均可,常写为私有(把类看成一个变量)
声明: friend + class +类名;(不是对象哦)
#include <iostream> using namespace std; class Bstruct { public: Bstruct() :Bvalue(23),name((char*)"ZHOU"){} friend class Astruct;//这是友元类的声明 private: int Bvalue; char* name; }; class Astruct//友元类定义,为了访问类Bstruct中的成员 { public: void function(Bstruct&); }; void Astruct::function(Bstruct& str) { cout <<"Bvalue is "<<str.Bvalue<<", name is "<<str.name<<endl; } int main(int argc, char const *argv[]) { Astruct A; Bstruct B; A.function(B); return 0; }
執行結果:
3。类Y的一个成员函数为类X的友元函数
使类B中的成员函数成为类A的友元函数,这样类B的该成员函数就可以访问类A的所有成员了。
当用到友元成员函数时,需注意友元声明和友元定义之间的相互依赖,在该例子中,类B必须先定义,否则类A就不能将一个B的函数指定为友元。然而,只有在定义了类A之后,才能定义类B的该成员函数。
更一般的讲,必须先定义包含成员函数的类,才能将成员函数设为友元。另一方面,不必预先声明类和非成员函数来将它们设为友元。
目的:使类Y的一个成员函数成为类X的友元,具体而言:在类Y的这个成员函数中,借助参数X,可以直接以X的私有变量
声明位置:声明在公有中 (本身为函数)
声明:friend + 成员函数的声明
调用:先定义Y的对象y---使用y调用自己的成员函数---自己的成员函数中使用了友元机制
#include <iostream> using namespace std; class Bstruct;//当用到友元成员函数时,需注意友元声明与友元定义之间的互相依赖。这是类Bstruct的声明 class Astruct { public: void function(Bstruct&);//该函数是类Bstruct的友元函数 }; class Bstruct { public: Bstruct() :Bvalue(23),name((char*)"ZHOU"){} friend void Astruct::function(Bstruct&);//该函数是友元成员函数的声明 int Bvalue; char* name; }; void Astruct::function(Bstruct& str)//只有在定义类Bstruct后才能定义该函数,毕竟,它被设为友元是为了访问类Bstruct的成员 { cout <<"Bvalue is "<<str.Bvalue<<", name is "<<str.name<<endl; } int main(int argc, char const *argv[]) { Bstruct B; Astruct A; A.function(B); return 0; }
執行結果:
友元函数和类的成员函数的区别
1 成员函数有this指针,而友元函数没有this指针。
2 友元函数是不能被继承的,就像父亲的朋友未必是儿子的朋友。