当前位置: 首页 > news >正文

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;
}

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

相关文章:

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

文章目录 1.友元1.什么是友元2.全局函数做友元2.类做友元3.成员函数做友元 1.友元 1.什么是友元 在C中&#xff0c;友元&#xff08;friend&#xff09;是一种允许一个类或函数访问另一个类的非公有&#xff08;private 或 protected&#xff09;成员的机制。这种机制打破了类…...

C#,JavaScript实现浮点数格式化自动保留合适的小数位数

目标 由于浮点数有漂移问题&#xff0c;转成字符串时 3.6 有可能得到 3.6000000000001&#xff0c;总之很长的一串&#xff0c;通常需要截取&#xff0c;但按照固定长度截取不一定能使用各种情况&#xff0c;如果能根据数值大小保留有效位数就好了。 C#实现 我们可以在基础库里…...

Android基础-工程目录结构说明

Android工程的项目目录结构是开发Android应用时的基础&#xff0c;它组织和存储了应用的所有源代码、资源和配置文件。了解并熟悉这个目录结构对于提高开发效率和代码管理至关重要。下面将详细阐述Android工程的项目目录结构。 1. 工程根目录 Android工程的根目录通常包含多个…...

浅谈提示词发展现状,Prompt 自动优化是未来。

#封面手绘于本科期间&#xff0c;当年在知乎上写的第一篇关于 AI 的文章就用的这个封面&#xff0c;聊表纪念。 这次我们来聊聊 Prompt. 本来想取一个类似“提示词不存在了…”&#xff0c;或是“再见&#xff0c;Prompt 课程…”的标题&#xff0c;但最近很多大佬的谬赞让我感…...

揭秘智能测径仪省钱之道!每年能为每条产线省上百万!

在当今竞争激烈的市场环境下&#xff0c;企业们都在不断寻求提高生产效率、降低成本的方法。而智能测径仪的出现&#xff0c;为圆形钢材、螺纹钢等生产企业实现这一目标提供了有力的支持。 智能测径仪被广泛应用于高线、铸管、圆钢、螺纹钢、钢筋等的轧制生产线中&#xff0c;进…...

echaerts图例自动滚动并隐藏翻页按钮

效果图 代码 legend: {itemHeight: 14,itemWidth: 14,height: "300", //决定显示多少个// 通过 CSS 完全隐藏翻页按钮pageButtonItemGap: 0,pageButtonPosition: end,pageIconColor: transparent, // 隐藏翻页按钮pageIconInactiveColor: transparent, // 隐藏翻页按…...

OpenCV的小部件最基本范例

OpenCV也有与PYQT类似的小部件&#xff0c;例如滑块slider。OpenCV可以用与PYQT类似的“信号与槽”方法&#xff0c;也可以在函数中直接查询小部件的值。 import cv2 import numpy as npcv2.namedWindow(Show1) image np.zeros((100, 400, 3), np.uint8) # 创建一个空白内容…...

内置类型知多少?

内置类型&#xff08;也称为基本类型或原生类型&#xff09;是C/C本身定义的数据类型&#xff0c;它们直接由编译器支持&#xff0c;不需要用户自定义。 内置类型主要包括以下几类&#xff1a; 1&#xff0e;算术类型&#xff1a; (1)整型&#xff1a;int、short、long、lon…...

【C++题解】1090 - 同因查找

问题&#xff1a;1090 - 同因查找 类型&#xff1a;for循环、简单循环 题目描述&#xff1a; 求出 10 至 1000 之内能同时被2、3、7 整除的数&#xff0c;并输出。 每行一个。 输入&#xff1a; 无。 输出&#xff1a; 按要求输出满足条件的数&#xff0c;每行 1 个。 完…...

uni微信小程序editor富文本组件如何插入图片

需求 在editor中插入图片&#xff0c;并对图片进行编辑&#xff0c;简略看一下组件的属性&#xff0c;官网editor 组件 | uni-app官网 解决方案 首先要使用到ready这个属性&#xff0c;然后官网有给代码粘过来&#xff0c;简单解释一下这段代码的意思&#xff08;作用是在不同…...

LabVIEW调用国产硬件DLL的稳定性问题及解决方案

在LabVIEW中调用国内公司提供的硬件DLL时&#xff0c;尽管可以运行&#xff0c;但常出现不稳定和bug问题&#xff0c;且厂家临时修改的版本未经长期测试。为确保稳定性和质量&#xff0c;需要制定系统化的测试和反馈机制、建立严格的版本控制、与厂家协作优化、并进行深入的自测…...

基础篇01——SQL的基本语法和分类

MySQL数据库安装与基本使用 安装教程参见&#xff1a;通过zip安装MySQL 通过命令行启动和停止MySQL服务命令 前提&#xff1a;安装MySQL成功之后 启动服务&#xff1a;net start mysql 停止服务&#xff1a;net stop mysql 通过命令行连接mysql 可以通过mysql的客户端命令行…...

HOW - 面试技巧系列 - 全英文面试

自我介绍 “can you tell me a little bit about yourself?” “please introduce yourself.” 工作经验 “can you describe your most recent job experience?” “how does your experience make you a good fit for this position?” 职业规划 “what are your l…...

【人工智能】第六部分:ChatGPT的进一步发展和研究方向

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…...

新能源管理系统主要包括哪些方面的功能?

随着全球对可持续发展和环境保护的日益重视&#xff0c;新能源管理系统已成为现代能源领域的核心组成部分。这一系统不仅涉及对新能源的收集、存储和管理&#xff0c;还包括对整个能源网络进行高效、智能的监控和控制。以下是新能源管理系统主要包含的几方面功能&#xff1a; 一…...

python如何快速的判断一个key在json的第几层呢,并修改其value值

python如何快速的判断一个key在json的第几层呢&#xff0c;并修改其value值 def find_and_modify_key(json_obj, target_key, new_value, current_level1):# 检查当前层是否包含目标keyif target_key in json_obj:print(f"找到 {target_key} 在第 {current_level} 层。&q…...

Python基础用语:揭示编程世界的底层逻辑与无限可能

Python基础用语&#xff1a;揭示编程世界的底层逻辑与无限可能 Python&#xff0c;这门强大的编程语言&#xff0c;如同一位神秘的导师&#xff0c;引领我们走进编程的奇妙世界。掌握Python的基础用语&#xff0c;不仅意味着我们能够驾驭这门语言&#xff0c;更意味着我们能够…...

react 中使用 swiper

最近项目中需要用到轮播图&#xff0c;我立马想起了 swiper &#xff0c;那么本文就来带大家体验一下如何在 React 中使用这个插件&#xff0c;使用的是 函数组 hooks 的形式。 需求非常简单&#xff0c;就是一个可以自动播放、点击切换的轮播图&#xff08;跑马灯&#xff0…...

2024年搭建知识库系统5大工具推荐

现如今&#xff0c;越来越多的企业开始了解并搭建知识库系统&#xff0c;想要带动企业员工的工作效率以提高企业运营效率。各种各样搭建知识库系统的工具应运而生&#xff0c;而如何在众多工具中&#xff0c;选择出最适合独特的企业产品的一个工具&#xff0c;成为企业亟待解决…...

Golang内存分配分三种Golang内存分配分三种类型

Golang内存分配分三种类型 线程缓存&#xff08;Thread Cache&#xff09; 拟人化解释&#xff1a;线程缓存就像是每个邮局员工的私人储物柜。每个员工都有自己的储物柜&#xff0c;用来暂时存放需要处理的小信件和包裹。当有新的信件或包裹需要处理时&#xff0c;员工会先看看…...

Netty-learning-example数据持久化实战:JPA+MySQL与MyBatis+MongoDB对比

Netty-learning-example数据持久化实战&#xff1a;JPAMySQL与MyBatisMongoDB对比 【免费下载链接】netty-learning-example :egg: Netty实践学习案例&#xff0c;见微知著&#xff01;带着你的心&#xff0c;跟着教程。我相信你行欧。 项目地址: https://gitcode.com/gh_mir…...

开源抢票工具成功率提升指南:从配置到实战的全方位优化

开源抢票工具成功率提升指南&#xff1a;从配置到实战的全方位优化 【免费下载链接】damaihelper 支持大麦网&#xff0c;淘票票、缤玩岛等多个平台&#xff0c;演唱会演出抢票脚本 项目地址: https://gitcode.com/gh_mirrors/dam/damaihelper 你是否曾在开票瞬间眼睁睁…...

基于STM32的充电桩控制器设计(有完整资料)

资料查找方式&#xff1a;特纳斯电子&#xff08;电子校园网&#xff09;&#xff1a;搜索下面编号即可编号&#xff1a;T4532205M设计简介&#xff1a;本设计是基于单片机的充电桩控制器设计&#xff0c;主要实现以下功能&#xff1a;1、RFID可以注册卡以及删除卡&#xff0c;…...

利用快马平台快速生成ffmpeg视频裁剪与滤镜添加原型

最近在做一个短视频处理的小工具&#xff0c;需要快速验证ffmpeg的视频裁剪和滤镜功能。传统方式要自己搭建环境、查文档、写代码&#xff0c;整个过程特别耗时。后来发现用InsCode(快马)平台可以省去这些麻烦&#xff0c;直接输入需求就能生成可运行的原型代码&#xff0c;特别…...

AI辅助游戏开发新体验:让快马平台的AI模型为你的Superpowers项目编写剧情与平衡技能

最近在尝试用Superpowers框架开发一款魔法题材的RPG游戏&#xff0c;发现InsCode(快马)平台的AI辅助功能特别适合快速原型开发。这里分享下如何用AI模型辅助完成游戏剧情脚本和技能平衡设计的实践过程。 剧情脚本生成 输入"魔法学校学徒发现古老卷轴"这个简单设定后&…...

GetQzonehistory:3步轻松永久备份QQ空间所有历史说说

GetQzonehistory&#xff1a;3步轻松永久备份QQ空间所有历史说说 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 还在担心QQ空间里那些承载青春记忆的说说会突然消失吗&#xff1f;GetQ…...

OpenClaw镜像体验:在星图GPU平台快速试用SecGPT-14B安全分析

OpenClaw镜像体验&#xff1a;在星图GPU平台快速试用SecGPT-14B安全分析 1. 为什么选择云平台体验OpenClaw 第一次接触OpenClaw时&#xff0c;我被它的自动化能力吸引&#xff0c;但本地安装过程让我望而却步。作为一个经常需要评估各种AI工具的安全工程师&#xff0c;我发现…...

QQ音乐加密文件解码终极指南:三分钟快速上手qmcdump工具教程

QQ音乐加密文件解码终极指南&#xff1a;三分钟快速上手qmcdump工具教程 【免费下载链接】qmcdump 一个简单的QQ音乐解码&#xff08;qmcflac/qmc0/qmc3 转 flac/mp3&#xff09;&#xff0c;仅为个人学习参考用。 项目地址: https://gitcode.com/gh_mirrors/qm/qmcdump …...

QMCDecode:让QQ音乐加密文件重获自由的macOS工具

QMCDecode&#xff1a;让QQ音乐加密文件重获自由的macOS工具 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac&#xff0c;qmc0,qmc3转mp3, mflac,mflac0等转flac)&#xff0c;仅支持macOS&#xff0c;可自动识别到QQ音乐下载目录&#xff0c;默认转换结…...

当创意遭遇围墙:AO3镜像站的破局与共建指南

当创意遭遇围墙&#xff1a;AO3镜像站的破局与共建指南 【免费下载链接】AO3-Mirror-Site 项目地址: https://gitcode.com/gh_mirrors/ao/AO3-Mirror-Site 问题象限&#xff1a;当同人爱好者遇上访问壁垒 解读创作自由的数字鸿沟 想象这样一个场景&#xff1a;深夜的…...