博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++扩展笔记3-1-1:C++友元函数和友元类用法谈
阅读量:5919 次
发布时间:2019-06-19

本文共 2805 字,大约阅读时间需要 9 分钟。

  hot3.png

一、友元函数:以以下代码为例:

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类的友元。

参考资料:

  1. Paul Deitel & Harvey Deitel, C++11程序设计(英文版)(第2版)
  2. 友元类学习笔记:
  3. 友元简介:

转载于:https://my.oschina.net/Samyan/blog/828590

你可能感兴趣的文章
spring boot hello world
查看>>
这两天遇到问题小结
查看>>
nginx反向代理配置及优化
查看>>
CSS3特性(动画、多列布局、伸缩布局)
查看>>
僵死进程
查看>>
android:configChanges="keyboardHidden|orientation"
查看>>
进一步优化Android ListView GridView中异步加载图片
查看>>
react native 组建卸载
查看>>
Fio随机读IOPS测试值可能偏大的原因分析
查看>>
唠唠SE的集合-05——LinkedList
查看>>
怎样解决ABBYY FineReader中的图片未检测到问题
查看>>
怎么给ABBYY FineReader 添加任务
查看>>
Android Support v4、v7、v13的区别和应用场景
查看>>
触屏手机左右滑动js插件
查看>>
composer的配置文件及用法
查看>>
Django2.2连接mysql数据库报错 mysqlclient 1.3.13 or newer is required; you have 0.9.3.
查看>>
nginx rewrite 404
查看>>
linux系统初始化& 优化总结文档
查看>>
debian6添加了insserv用来代替update-rc.d
查看>>
读《分布式系统原理与泛型》有感
查看>>