当前位置: 首页 > 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;员工会先看看…...

多语言翻译工作流:OpenClaw协同千问3.5-27B实现文档自动本地化

多语言翻译工作流&#xff1a;OpenClaw协同千问3.5-27B实现文档自动本地化 1. 为什么需要智能翻译流水线&#xff1f; 去年参与一个开源项目时&#xff0c;我遇到了文档翻译的噩梦。团队需要将技术文档同步翻译成英、日、韩三种语言&#xff0c;传统流程是&#xff1a;先用机…...

新手零基础入门:用快马ai生成你的第一个arduino流水灯程序

作为一个刚接触Arduino的新手&#xff0c;我最近在InsCode(快马)平台上完成了第一个LED流水灯项目。整个过程比我预想的顺利很多&#xff0c;特别适合零基础的朋友入门体验。下面分享我的学习过程和几点实用心得&#xff1a; 硬件准备其实很简单 只需要一块Arduino UNO开发板和…...

从RGB合并到多传感器融合:深入拆解AXI4-Stream Combiner IP在Zynq平台上的两种典型应用

从RGB合并到多传感器融合&#xff1a;深入拆解AXI4-Stream Combiner IP在Zynq平台上的两种典型应用 在FPGA开发中&#xff0c;数据流的高效处理一直是工程师面临的核心挑战之一。当系统需要同时处理多个并行数据源时&#xff0c;如何将这些数据流有序、高效地合并为单一数据流…...

如何用OpenRPA实现企业级流程自动化?开源RPA工具完整指南

如何用OpenRPA实现企业级流程自动化&#xff1f;开源RPA工具完整指南 【免费下载链接】openrpa Free Open Source Enterprise Grade RPA 项目地址: https://gitcode.com/gh_mirrors/op/openrpa 在数字化转型浪潮中&#xff0c;企业面临着效率瓶颈与成本压力的双重挑战。…...

Magisk模块开发实战指南:从基础架构到高级功能实现

Magisk模块开发实战指南&#xff1a;从基础架构到高级功能实现 【免费下载链接】Magisk The Magic Mask for Android 项目地址: https://gitcode.com/GitHub_Trending/ma/Magisk Magisk模块开发是Android系统定制领域的核心技术&#xff0c;它通过独特的挂载机制让开发者…...

Claude Code 常用技巧:这几个操作让我开发效率翻倍

Claude Code 常用技巧&#xff1a;这几个操作让我开发效率翻倍 说实话&#xff0c;用 Claude Code 差不多也有小半年了&#xff0c;从一开始"就这&#xff1f;"的怀疑&#xff0c;到现在每天开工第一件事就是把它招呼进来&#xff0c;中间踩了不少坑&#xff0c;也真…...

如何通过抖音批量下载工具实现高效内容管理与分析

如何通过抖音批量下载工具实现高效内容管理与分析 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖音批量下载…...

小红书数据采集实战指南:3种高效方法解决内容分析难题

小红书数据采集实战指南&#xff1a;3种高效方法解决内容分析难题 【免费下载链接】xhs 基于小红书 Web 端进行的请求封装。https://reajason.github.io/xhs/ 项目地址: https://gitcode.com/gh_mirrors/xh/xhs 小红书作为中国最大的生活方式分享平台&#xff0c;每天产…...

NCM格式转换技术解析:从加密限制到音频自由的技术实现

NCM格式转换技术解析&#xff1a;从加密限制到音频自由的技术实现 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 一、问题场景&#xff1a;数字音乐的格式枷锁与用户困境 1.1 音乐人的设备兼容困境 独立音乐人小林最近遇到了一个…...

OFA-VQA镜像可解释性增强:Grad-CAM热力图可视化答案依据区域

OFA-VQA镜像可解释性增强&#xff1a;Grad-CAM热力图可视化答案依据区域 1. 引言&#xff1a;为什么需要可视化VQA模型的决策依据&#xff1f; 当我们使用视觉问答&#xff08;VQA&#xff09;模型时&#xff0c;经常会遇到一个关键问题&#xff1a;模型给出的答案真的可靠吗…...