百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

C++中的友元(C++ friend)

liebian365 2025-01-21 19:15 14 浏览 0 评论

什么是友元

C++规定私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行。这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦。
C++ 设计者们认为,如果有的程序员真的非常怕麻烦,就是想在类的成员函数外部直接访问对象的私有成员,那还是做一点妥协以满足他们的愿望为好,这也算是眼前利益和长远利益的折中。因此,C++ 就有了
友元(friend)的概念,简单点理解就是:朋友是值得信任的,所以可以对他们公开自己的隐私。

相比与c++而言,java就直接去掉了友元。C++由于是从结构化的C语言发展而来的,需要照顾结构化设计程序员的习惯,所以在对私有成员可访问范围的问题上不可限制太死。

友元分两种:友元类、友元函数。

友元类

  • 友元类定义

一个类 A 可以将另一个类 B 声明为自己的友元,类 B 的所有成员函数就都可以访问类 A 对象的私有成员。在类定义中声明友元类的写法为:

friend class 类名;
  • 友元类使用示例
class CCar {
private:
    int price;
    friend class CDriver;  
};
class CDriver {
public:
    CCar myCar;
    void ModifyCar() { 
        myCar.price += 1000;  
    }
};

第 4 行使得 CDriver 类的所有成员函数都能访问 CCar 对象的私有成员。如果没有第 5 行,第 10 行对 myCar 私有成员 price 的访问就会导致编译错误。

  • 友元类的特点

1)一般来说,类 A 将类 B 声明为友元类,则类 B 最好从逻辑上和类 A 有比较接近的关系。例如上面的例子,CDriver 代表司机,CCar 代表车,司机拥有车,所以 CDriver 类和 CCar 类从逻辑上来讲关系比较密切,把 CDriver 类声明为 CCar 类的友元比较合理。

2)友元类不具备传递性,即类 A 是类 B 的友元,类 B 是类 C 的友元,并不能导出类 A 是类 C 的友元。

友元函数

  • 友元函数定义

在定义一个类的时候,可以把一些函数(包括全局函数和其他类的成员函数)声明为“友元”,这样那些函数就成为该类的友元函数,在友元函数内部就可以访问该类对象的私有成员了。
将全局函数声明为友元的写法为:

friend 返回值类型 函数名(参数表);

将其他类的成员函数声明为友元的写法为:

friend 返回值类型 其他类的类名::成员函数名(参数表);

注意:不能把其他类的私有成员函数声明为友元。

  • 友元函数示例
#include<iostream>
using namespace std;

class CCar;  //提前声明CCar类,以便后面的CDriver类使用
class CDriver {
public:
    void ModifyCar(CCar* pCar);  
};
class CCar {
private:
    int price;
    friend int MostExpensiveCar(CCar cars[], int total);  //声明友元
    friend void CDriver::ModifyCar(CCar* pCar);  //声明友元
};
void CDriver::ModifyCar(CCar* pCar) {
    pCar->price += 1000;  
}
int MostExpensiveCar(CCar cars[], int total) { 
    int tmpMax = -1;
    for (int i = 0; i<total; ++i)
        if (cars[i].price > tmpMax)
            tmpMax = cars[i].price;
    return tmpMax;
}

第 12 行将全局函数 MostExpensiveCar 声明为 CCar 类的友元,因此在第 21 行可以访问 cars[i] 的私有成员 price。同理,第 14 行将 CDriver 类的 ModifyCar 成员函数声明为友元,因此在第 18 行可以访问 pCar 指针所指向的对象的私有成员变量 price。

总结

友元,看起来很灵活但是也使得面向对象变得更加凌乱,使用友元的代码往往很难阅读与维护,所以对于新开发的代码还是应该像java语言那样,将需要对外使用的私有变量通过成员函数来暴露出去,而尽量少使用友元。

相关推荐

4万多吨豪华游轮遇险 竟是因为这个原因……

(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...

“菜鸟黑客”必用兵器之“渗透测试篇二”

"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...

科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白

作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...

麦子陪你做作业(二):KEGG通路数据库的正确打开姿势

作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...

知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势

智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...

每日新闻播报(September 14)_每日新闻播报英文

AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...

香港新巴城巴开放实时到站数据 供科技界研发使用

中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...

5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper

本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...

Qt动画效果展示_qt显示图片

今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...

如何从0到1设计实现一门自己的脚本语言

作者:dong...

三年级语文上册 仿写句子 需要的直接下载打印吧

描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...

C++|那些一看就很简洁、优雅、经典的小代码段

目录0等概率随机洗牌:1大小写转换2字符串复制...

二年级上册语文必考句子仿写,家长打印,孩子照着练

二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...

一年级语文上 句子专项练习(可打印)

...

亲自上阵!C++ 大佬深度“剧透”:C++26 将如何在代码生成上对抗 Rust?

...

取消回复欢迎 发表评论: