一、友元函数:以以下代码为例:
Counter.h文件:
#ifndef COUNTER_H#define COUNTER_Hclass Counter { friend void setX(Counter &, int); // friend declaration ...此处先省略两行 //This is not usable in netbeans and Linux: friend void Cracker::crackCounterA(Counter &, int); public: Counter(); ~Counter(); // output x void printX() const; //把x的值打出来而已 。。。此处也先省略两行private: int x; //初始值是0 //...此处也先省略两行};void setX( Counter &c, int val );#endif /* COUNTER_H */
Counter.cpp文件:
//。。。此处略去文件头和具体实现。// function setX can modify private data of Count // because setX is declared as a friend of Count (line 9)void setX( Counter &c, int val ){ c.x = val; // allowed because setX is a friend of Count} // end function setX
此时,类之外的setX函数由于在类中已经被定义为友元函数,因此是可以修改Counter的私有变量x的。因此setX函数是Counter类的友元函数。main方法中调用示例如下:
Counter counter; // create Count object cout << "counter.x after instantiation: "; counter.printX(); setX( counter, 8 ); // set x using a friend function cout << "counter.x after call to setX friend function: "; counter.printX();
运行效果:
这里声明,根据《C++11》作者呆头先生的说法,这个项目最好分为三个文件,即上面提到的Counter.h、Counter.cpp和一个含有主方法的测试文件。
二、友元类:以上述版本基础上进一步修改的代码为例:
class Counter { friend void setX(Counter &, int); // friend declaration // 。。。这里之前都一样 friend class Modifier; //新增的一行 void printX() const; // 。。。这里之前也都一样 void printY() const; //新增的一个方法,仅仅打出yprivate: int x; int y; //新增的一行,初始值为1};
新建的文件Modifier.h:
#ifndef MODIFIER_H#define MODIFIER_H#include "Counter.h"class Modifier {public: Modifier(int num); //初始化时让para = num即可 void setCounter(Counter &c); ~Modifier(); private: int para;};#endif /* MODIFIER_H */
Modifier.h重点部分:
void Modifier::setCounter(Counter& c){ c.y = para;}
这样,我们就实现了在Modifer这个类中对于Counter类中私有变量y的修改。调用示例和运行结果如下:
cout << "counter.y after instantiation: "; counter.printY(); Modifier modifier(7); modifier.setCounter(counter); cout << "counter.y after call to setY friend function: "; counter.printY();
那么问题来了。我们既可以让一个函数成为某个类的友元函数,又可以让一整个类成为某个类的友元类,是否可以让某个类的仅仅一个或几个函数成为另一个类的友元函数呢?
三、友元成员函数
关于这个问题,博主在个人的netbeans和Linux上都试过相应的例子,然而均以失败告终。因此查阅了相关资料,也是公说公有理婆说婆有理,翻遍呆头的书也没交代清楚,因此博主对于这个问题目前还在研究当中,也期待各位网友与博主分享自己的代码。以下参考资料中两个博客博主认为写得不错,因此也转载了一下。如有研究结果会及时进行更新。目前的研究结果来看,网上盛传的以下代码事实上是**编译错误**的。
文件AClass.h
class A;class B{public: void show(A &t, int num){t.i = num;}};class A{private: int i;public: A(){ i = 0;} friend void B::show(A &t); ~A(){}};
主方法:
#include "AClass.h"using namespace std;int main(int argc, char** argv) { A a; B b; b.show(a, 15); return 0;}
总结
友元函数和友元类的修改实现了在有限范围内对于私有变量的修改。特别要注意,也正如很多资料提到的,友元是授权的,而不是自动获取的。比如B类是A类的友元,反过来就不一定成立,除非A类中明确定义B类是其友元。还有友元是不可传递的,接着上例,若C类是B类的友元,则C类不一定是A类的友元。
参考资料:
- Paul Deitel & Harvey Deitel, C++11程序设计(英文版)(第2版)
- 友元类学习笔记:
- 友元简介: