C++核心编程友元的应用

文章目录

      • 1.友元
        • 1.什么是友元
        • 2.全局函数做友元
        • 2.类做友元
        • 3.成员函数做友元

1.友元

1.什么是友元

在C++中,友元(friend)是一种允许一个类或函数访问另一个类的非公有(private 或 protected)成员的机制。这种机制打破了类的封装性,因此在使用时需要谨慎。然而,在某些情况下,友元提供了一种方便的方式来实现特定的功能,如操作符重载、输入输出流操作等。

友元可以是另一个类、类的成员函数、或者全局函数。当一个类或函数被声明为另一个类的友元时,它就可以访问那个类的所有私有和保护成员。

2.全局函数做友元

全局函数(非类成员函数)也可以被声明为类的友元。这样做允许全局函数访问类的私有(private)和保护(protected)成员。

#include <iostream>class MyClass {// 声明全局函数 friendFunc 为友元friend void friendFunc(MyClass& obj);private:int secretValue;public:MyClass(int value) : secretValue(value) {}
};// 全局函数,它可以访问 MyClass 的私有成员
void friendFunc(MyClass& obj) {std::cout << "Secret value: " << obj.secretValue << std::endl;
}int main() {MyClass myObj(42);friendFunc(myObj);  // 输出: Secret value: 42return 0;
}

在这个例子中,friendFunc 是一个全局函数,它被声明为 MyClass 的友元。因此,friendFunc 可以访问 MyClass 的私有成员 secretValue。在 main 函数中,我们创建了一个 MyClass 对象 myObj,并将其传递给 friendFunc,后者成功输出了 secretValue 的值。

2.类做友元

在C++中,一个类也可以被声明为另一个类的友元。当一个类被声明为另一个类的友元时,这个友元类可以访问另一个类的私有(private)和保护(protected)成员。这种机制在某些情况下可能很有用,特别是当两个类需要紧密协作,并且一个类需要直接访问另一个类的内部数据时。

#include <iostream>class MyClass {// 声明另一个类(例如 MyFriendClass)为友元friend class MyFriendClass;private:int secretValue;public:MyClass(int value) : secretValue(value) {}// 提供一个公共函数以显示secretValue的值(仅用于比较)void displaySecretValue() const {std::cout << "Secret value: " << secretValue << std::endl;}
};// 友元类 MyFriendClass
class MyFriendClass {
public:// MyFriendClass 可以访问 MyClass 的私有成员void printSecret(const MyClass& obj) {std::cout << "MyFriendClass sees: " << obj.secretValue << std::endl;}
};int main() {MyClass myObj(42);MyFriendClass friendObj;// 通过 MyClass 的公共函数显示 secretValuemyObj.displaySecretValue(); // 输出: Secret value: 42// 通过 MyFriendClass 访问 MyClass 的私有成员friendObj.printSecret(myObj); // 输出: MyFriendClass sees: 42return 0;
}

在这个例子中,MyFriendClass 被声明为 MyClass 的友元。因此,MyFriendClass 中的成员函数 printSecret 可以访问 MyClass 对象的 secretValue 成员,即使它是私有的。注意,友元关系不是双向的;即 MyClass 不是 MyFriendClass 的友元,除非另外声明。

使用类作为友元时要特别小心,因为它破坏了封装性,并可能导致代码难以维护和理解。在可能的情况下,最好使用公共接口和受保护的成员来实现类之间的协作。然而,在某些情况下,类作为友元可能是实现特定功能所必需的。

3.成员函数做友元

在C++中,成员函数本身并不直接作为另一个类的友元,因为成员函数是类的一部分,它总是能够访问其所在类的所有成员(包括私有和保护成员)。然而,你可以将一个类的成员函数声明为另一个类的友元,但实际上是将这个成员函数所属的整个类声明为友元。

但如果你想让另一个类的成员函数能够访问当前类的私有或保护成员,你应该做的是将该成员函数所在的整个类声明为当前类的友元。

#include <iostream>class MyClass {// 声明另一个类(例如 OtherClass)为友元friend class OtherClass;private:int secretValue;public:MyClass(int value) : secretValue(value) {}// 提供一个公共函数以显示secretValue的值(仅用于比较)void displaySecretValue() const {std::cout << "Secret value: " << secretValue << std::endl;}
};class OtherClass {
public:// 这个成员函数可以访问 MyClass 的私有成员void printSecret(const MyClass& obj) {std::cout << "OtherClass sees: " << obj.secretValue << std::endl;}
};int main() {MyClass myObj(42);OtherClass friendObj;// 通过 MyClass 的公共函数显示 secretValuemyObj.displaySecretValue(); // 输出: Secret value: 42// 通过 OtherClass 的成员函数访问 MyClass 的私有成员friendObj.printSecret(myObj); // 输出: OtherClass sees: 42return 0;
}

在这个例子中,OtherClass 被声明为 MyClass 的友元,这意味着 OtherClass 的所有成员函数(不仅仅是 printSecret)都可以访问 MyClass 的私有成员。然而,在实际编程中,通常最好只将真正需要访问私有成员的成员函数所在的类声明为友元,以保持封装的完整性。

//
// Created by 86189 on 2024/6/6.
//
#include "iostream"
using namespace std;class myClassFriend;
class myClass{
public:myClass();void visit();myClassFriend *myClassfriend;
};
class myClassFriend{friend void  myClass::visit();;
public:myClassFriend();
public:string name;
private:string sex;
};myClassFriend::myClassFriend() {name = "张三";sex = "男";
}myClass::myClass() {myClassfriend = new myClassFriend;
}void myClass::visit() {cout << myClassfriend->name << endl;cout << myClassfriend->sex << endl;
}int main() {myClass myclass;myclass.visit();delete myclass.myClassfriend;return 0;
}

只通过成员函数访问另一个类的私有成员。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/23320.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统研发安全漏洞

软件安全漏洞指的是软件中存在的具体缺陷或疏忽&#xff0c;这些缺陷或疏忽能够被攻击者利用并执行一些恶意行为。这些行为包括但不限于泄露或修改敏感信息、干扰或销毁系统、接管计算机系统或程序权限等。与大众熟悉的软件缺陷&#xff08;Bug&#xff09;相比&#xff0c;安全…

Mysql中表的常用约束

在MySQL表中常用的约束有以下几种&#xff1a; 1. 主键约束&#xff08;Primary Key Constraint&#xff09;&#xff1a;用于标识表中的唯一记录。一个表只能有一个主键&#xff0c;主键列不能有重复值&#xff0c;也不能为NULL。 2. 唯一约束&#xff08;Unique Constraint…

2024050402-重学 Java 设计模式《实战责任链模式》

重学 Java 设计模式&#xff1a;实战责任链模式「模拟618电商大促期间&#xff0c;项目上线流程多级负责人审批场景」 一、前言 场地和场景的重要性 射击&#x1f3f9;需要去靶场学习、滑雪&#x1f3c2;需要去雪场体验、开车&#x1f697;需要能上路实践&#xff0c;而编程…

Scanpy(4)用与数据整合和批次处理

Scanpy包,用与数据整合和批次处理,包含批次效应的BBKNN算法和用于对比的ingest基础算法比较,及其原理简介。 1. 依赖: (1)数据集(全部需要挂VPN): PBMC:pbmc3k_processed()(需要下载);pbmc68k_reduced()(scanpy自带)Pancreas(需要下载)(2)Python包:Scanp…

【Python】把xmind转换为指定格式txt文本

人工智能训练通常需要使用文本格式&#xff0c;xmind作为一种常规格式不好进行解析&#xff0c;那如何把xmind转换为txt格式呢&#xff1f; 软件信息 python python -v Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)] on win32…

Python 包安装及常用命令【python 入门】

背景&#xff1a; 近期看到一个项目&#xff0c;做微信只能机器人&#xff0c;服务是使用python搭建的&#xff0c;于是拷贝下来自己打算跑一跑&#xff0c;部署一下&#xff0c;可是自己又没有python的经验&#xff0c;于是各种查资料学习&#xff0c;跟着敲一敲&#xff0c;顺…

Go 1.19.4 切片与子切片-Day 05

1. 切片 1.1 介绍 切片在Go中是一个引用类型&#xff0c;它包含三个组成部分&#xff1a;指向底层数组的指针&#xff08;pointer&#xff09;、切片的长度&#xff08;length&#xff09;以及切片的容量&#xff08;capacity&#xff09;&#xff0c;这些信息共同构成了切片的…

单片机排水泵高压方案

灵动微多颗算力高、高可靠性的通用系列和电机专用系列MCU&#xff0c;配合成熟的控制算法&#xff0c;覆盖了包括洗衣机在内的各种大小家电市场。 RAMSUN提供的MM32 MCU种类较多&#xff0c;例如洗衣机内部的排水泵系统&#xff0c;排水泵控制首选电控高性价比产品MM32SPIN023…

JavaWeb_SpringBootWeb案例

环境搭建&#xff1a; 开发规范 接口风格-Restful&#xff1a; 统一响应结果-Result&#xff1a; 开发流程&#xff1a; 第一步应该根据需求定义表结构和定义接口文档 注意&#xff1a; 本文代码从上往下一直添加功能&#xff0c;后面的模块下的代码包括前面的模块&#xff0c…

Xmind Pro 2024 专业版激活码(附下载链接)

说到思维导图&#xff0c;就不能不提 Xmind。这是一款优秀的思维导图工具&#xff0c;拥有着丰富的导图模板&#xff0c;漂亮的界面和配色&#xff0c;以及各种各样的创意工具。 新架构速度更快 采用全新 Snowdancer 引擎&#xff0c;一种堪称「黑科技」的先进图形渲染技术。…

翘首以盼的抗锯齿

Antialiasing 实际的图形学中是怎么实现反走样的呢&#xff1f; 我们不希望实际产出的图形有锯齿效果&#xff0c;那怎么办呢&#xff1f; 从采样的理论开始谈起吧 Simpling theory 照片也是一种采样&#xff0c;把景象打散成像素放到屏幕上的过程&#xff1a; 还可以在不…

14、企业数据资源相关会计处理暂行规定

为规范企业数据资源相关会计处理, 强化相关会计信息披露, 根据《中华人民共和国会计法》 和企业会计准则等相关规定, 现对企业数据资源的相关会计处理规定如下: 一、 关于适用范围 本规定适用于企业按照企业会计准则相关规定确认为无形资产或存货等资产类别的数据资源,以…

21 - 即时食物配送 II(高频 SQL 50 题基础版)

21 - 即时食物配送 II -- sum(if(order_datecustomer_pref_delivery_date,1,0))/count(*)sum(order_datecustomer_pref_delivery_date)/count(*) -- count(*),表示数据的行数&#xff0c;如果有分组&#xff0c;为分组后数据的行数select round(100*sum(if(order_datecustomer_…

【名词解释】Unity的Button组件及其使用示例

Unity的Button组件是Unity引擎中UI系统的一部分&#xff0c;它允许用户创建可交互的按钮&#xff0c;用户可以点击这些按钮来触发事件。Button组件通常用于游戏界面中&#xff0c;比如开始游戏、暂停游戏、选择选项等。 Button组件的主要属性包括&#xff1a; interactable: …

原来Stable Diffusion是这样工作的

stable diffusion是一种潜在扩散模型&#xff0c;可以从文本生成人工智能图像。为什么叫做潜在扩散模型呢&#xff1f;这是因为与在高维图像空间中操作不同&#xff0c;它首先将图像压缩到潜在空间中&#xff0c;然后再进行操作。 在这篇文章中&#xff0c;我们将深入了解它到…

达摩院重大“遗产”!fluxonium量子比特初始化300纳秒且保真度超过99%

通用量子计算机开发的主要挑战之一是制备量子比特。十多年来&#xff0c;研究人员在构建量子计算机的过程中主要使用了transmon量子比特&#xff0c;这也是迄今为止商业上最成功的超导量子比特。 但与业界多数选择transmon量子比特不同&#xff0c;&#xff08;前&#xff09;…

npm运行报错:无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本问题解决

问题其实已经显而易见了 系统禁止运行脚本 以管理员身份运行 PowerShell&#xff1a; 右键点击“开始”按钮或按 Win X&#xff0c;然后选择“Windows PowerShell(管理员)”。 查看当前执行策略&#xff1a; 在 PowerShell 中输入以下命令来查看当前的执行策略&#xff1a; G…

Python文本处理利器:jieba库全解析

文章目录 Python文本处理利器&#xff1a;jieba库全解析第一部分&#xff1a;背景和功能介绍第二部分&#xff1a;库的概述第三部分&#xff1a;安装方法第四部分&#xff1a;常用库函数介绍1. 精确模式分词2. 全模式分词3. 搜索引擎模式分词4. 添加自定义词典5. 关键词提取 第…

服务器遭遇UDP攻击时的应对与解决方案

UDP攻击作为分布式拒绝服务(DDoS)攻击的一种常见形式&#xff0c;通过发送大量的UDP数据包淹没目标服务器&#xff0c;导致网络拥塞、服务中断。本文旨在提供一套实用的策略与技术手段&#xff0c;帮助您识别、缓解乃至防御UDP攻击&#xff0c;确保服务器稳定运行。我们将探讨监…

最新PHP众筹网站源码 支持报名众筹+商品众筹+公益众筹等多种众筹模式 含完整代码包和部署教程

在当今互联网飞速发展的时代&#xff0c;众筹模式逐渐成为了创新项目、商品销售和公益活动融资的重要渠道。分享一款最新版的PHP众筹网站源码&#xff0c;支持报名众筹、商品众筹和公益众筹等多种众筹模式。该源码包含了完整的代码包和详细的部署教程&#xff0c;让新手也可以轻…