C++基础语法:友元
前言
"打牢基础,万事不愁" .C++的基础语法的学习."学以致用,边学边用",编程是实践性很强的技术,在运用中理解,总结.
以<C++ Prime Plus> 6th Edition(以下称"本书")的内容开展学习
引入
友元提供了一种特别的方式,访问对象私有数据.
友元有三种方式:友元非成员函数;友元类;友元成员函数;
从私有数据的访问说起
举例:建立一个Person类,声明年龄和姓名属性
main.h
#include<iostream>
using namespace std;class Person {string name;int age;
public:Person(const string& str,int ag):name(str),age(ag){}int getAge() const{ return age; }string getName() const{ return name; }
};
main.cpp //测试代码
#include<iostream>
#include"main.h"int main(void) {Person xiaozhang("小张", 35);cout << "小张的年龄是:" << xiaozhang.getAge() << endl; //通过公开的接口访问私有数据
// cout << "小张的年龄是:" << xiaozhang.age << endl; //无法访问私有数据
}
----根据"数据私有,接口公开"这个编码原则,访问对象属性必须通过public中的接口函数
友元的各种实现
1.友元非成员函数
在public中定义一个打印对象信息的函数
经典代码(在本书P394)一是使用了友元访问私有数据,二是链式调用,不影响原有的cout
注:所谓经典代码,可以背下来的代码
friend ostream & operator<<(ostream& os, Person person) { //友元非成员函数定义//可以使用erson.name和person.age了os << "姓名为:" << person.name << "年龄为:" << person.age << endl; return os; //返回引用,链式调用
}
说明:可以在同Person类的文件中定义,这里为了方便写成了内联函数.
测试代码,在main.cpp中添加
cout << xiaozhang; //调用友元函数
和接口函数的区别:用"对象.属性"取得属性值,而不是调用上面的接口函数"对象.getAge()",看起来更形象.
2.友元类
在Person类中声明友元类
friend class Friend; //友元类
编写友元类
这里用了两种方式:一是传入原始类对象引用,二是原始类对象依赖(也就是把原始类对象引用作形参传入)
class Friend { //Person的友元类FriendPerson& person;
public:Friend(Person& pe):person(pe){}//传入对象引用,对象.属性访问void print() { cout <<"朋友姓名是:"<< person.name<<"," << "年龄是:" << person.age << endl;}//添加依赖,对象.属性访问void print2(Person& person2){ cout << "朋友姓名是:" << person2.name << "," << "年龄是:" << person2.age << endl; }
};
测试代码,在main.cpp中添加
Friend xz_friend(xiaozhang); //友元类对象
xz_friend.print();Person laoli("老李", 45); //友元类依赖
xz_friend.print2(laoli);
说明:因为声明了友元类,所以在Friend类中访问Person类的属性,也是对象.属性.
3. 友元成员函数
本书P607有相关描述,原始类和使用友元成员函数的类先后顺序有要求,需要前向声明原始类,代码如下: 1234表示顺序
class Person; //1原始类前向声明,为使用友元成员函数的类准备class FriendFun { //2使用友元成员函数的类double money;
public:FriendFun(double mo) :money(mo) {}void set_age(Person& person, int ag); //友元成员函数不能写成内联函数,必须写在外面
};class Person { //3原始类string name;int age;
public:Person(const string& str,int ag):name(str),age(ag){}int getAge() const{ return age; }string getName() const{ return name; }//声明友元成员函数friend void FriendFun::set_age(Person& person, int ag);
};//4定义在类外的友元成员函数
void FriendFun::set_age(Person& person, int ag) { person.age = ag; //对象.属性访问原始类私有数据
}
注意:
顺序如下:1原始类前向声明→2使用友元成员函数的类声明→3原始类声明→4友元成员函数定义
测试代码,在main.cpp中添加
//生成友元成员函数所在的类对象
FriendFun ff(5000);
//传入原始类对象,调用友元成员函数,修改原始对象数据
ff.set_age(xiaozhang,30);
//看是否改变了原始对象的数据
cout << "小张的年龄是:" << xiaozhang.getAge() << endl;
友元的分析
1.不管是哪一种友元,都是以"对象.属性"访问将其视为友元的原始类对象数据
2.如1所述,友元不能单独存在,必须要使用原始对象引用,他的形式可以是函数形参,也可以是传给友元类的属性.
友元的思考
1.友元是否破坏了数据的封装性?
不会.使用友元是为了以一种友好的方式访问私有数据.如果不使用友元,也可以通过包含对象引用,再通过接口函数来访问.和枚举一样,友元虽然不是必须的,但在某些情况下会比较方便.
2.怎样概括友元?
友元是一种授权.他授权其他成员函数或者非成员函数访问或者修改对象的私有属性.
小结
对友元的一些理解和使用.
C++在"数据可见性"上有很多的定义,比如私有公有,命名空间,类作用域,还有这里的友元.有一种简便的写法:所有数据公开,然后根据情况调整.
相关文章:
C++基础语法:友元
前言 "打牢基础,万事不愁" .C的基础语法的学习."学以致用,边学边用",编程是实践性很强的技术,在运用中理解,总结. 以<C Prime Plus> 6th Edition(以下称"本书")的内容开展学习 引入 友元提供了一种特别的方式,访问对象私有数据. 友元有三…...

【大模型系列】Video-LaVIT(2024.06)
Paper:https://arxiv.org/abs/2402.03161Github:https://video-lavit.github.io/Title:Video-LaVIT: Unified Video-Language Pre-training with Decoupled Visual-Motional TokenizationAuthor:Yang Jin, 北大&#x…...

【总结】nacos作为注册中心-应用启动失败:NacosDiscoveryProperties{serverAddr=‘127.0.0.1:8848‘……
问题现象 启动springboot应用时报错,能够读取到nacos配置,但是使用nacos作为注册中心,应用注册到nacos失败。 应用配置bootstrap.properties如下: # 应用编码,安装时替换变量 spring.application.namedata-center #…...
C语言——数组和排序
C语言——数组和排序 数组数组的概念数组的初始化数组的特点 排序选择排序冒泡排序插入排序 二分查找 数组 数组的概念 数组是一组数据 ; 数组是一组相同类型的数据或变量的集合 ; 应用场景: 用于批量的处理多个数据 ; 语法&…...
QEMU 新增QMPHMP指令【原文阅读】
文章目录 0x0 QEMU原文0x10x11 How to write monitor commands0x12 Overview0x13 Testing 0x20x21 Writing a simple command: hello-world0x22 Arguments 0x30x31 Implementing the HMP command 0x40x41 Writing more complex commands0x42 Modelling data in QAPI0x43 User D…...

【Linux】全志Tina配置屏幕时钟的方法
一、文件位置 V:\f1c100s\Evenurs\f1c100s\tina\device\config\chips\c200s\configs\F1C200s\sys_config.fex 二、文件内容 三、介绍 在此处可以修改屏幕的频率,当前为21MHz。 四、总结 注意选择对应的屏幕的参数,sdk所支持的屏幕信息都在此文件夹中…...
探索WebKit的CSS表格布局:打造灵活的网页数据展示
探索WebKit的CSS表格布局:打造灵活的网页数据展示 CSS表格布局是一种在网页上展示数据的强大方式,它允许开发者使用CSS来创建类似于传统HTML表格的布局。WebKit作为许多流行浏览器的渲染引擎,提供了对CSS表格布局的全面支持。本文将深入探讨…...

信号的运算
信号实现运算,首先要明确,电路此时为负反馈电路,当处于深度负反馈时,可直接使用虚短虚断。负反馈相关内容可见:放大电路中的反馈_基极反馈-CSDN博客https://blog.csdn.net/qq_63796876/article/details/140438759 一、…...
Vue3知识点汇总
创建项目 npm init vuelatest // npm create vitelatestVue文件结构 <!-- 开关:经过语法糖的封装,容许在script中书写组合式API --> <!-- setup在beforeCreate钩子之前自动执行 --> <script setup><!-- 不再要求唯一根元素 -->…...
C++设计模式--单例模式
单例模式的学习笔记 单例模式是为了:在整个系统生命周期内,保证一个类只能产生一个实例,确保该类的唯一性 参见链接1,链接2 #include <iostream> #include <mutex>using namespace std;/*懒汉模式:只有在…...

数据驱动未来:构建下一代湖仓一体电商数据分析平台,引领实时商业智能革命
1.1 项目背景 本项目是一个创新的湖仓一体实时电商数据分析平台,旨在为电商平台提供深度的数据洞察和业务分析。技术层面,项目涵盖了从基础架构搭建到大数据技术组件的集成,采用了湖仓一体的设计理念,实现了数据仓库与数据湖的有…...
学习JavaScript第五天
文章目录 1.HTML DOM1.1 表单相关元素① form 元素② 文本输入框类和文本域(input 和 textarea)③ select 元素 1.2 表格相关元素① table 元素② tableRow 元素(tr 元素)③ tableCell 元素 (td 或 th) 1.3…...

pythonGame-实现简单的坦克大战
通过python简单复现坦克大战游戏。 使用到的库函数: import turtle import math import random import time 游戏源码: import turtle import math import random import time# 设置屏幕 screen turtle.Screen() screen.setup(800, 600) screen.tit…...
不太常见的asmnet诊断
asm侦听 [griddb1-[ASM1]-/home/grid]$ srvctl config asm ASM home: <CRS home> Password file: OCR/orapwASM Backup of Password file: OCRDG/orapwASM_backup ASM listener: LISTENER ASM instance count: 3 Cluster ASM listener: ASMNET1LSNR_ASM[rootdb1:/root]# …...

双指针-【3,4,5,6,7,8】
第三题:快乐数 . - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/happy-number/算法思想: 1.每个…...
react Vant中如何获取步进器的值
在React中使用Vant(一个轻量、可靠的移动端Vue组件库,虽然原生是为Vue设计的,但如果你在使用的是React版本的Vant,比如通过某些库或框架桥接Vue组件到React,或者是一个类似命名的React UI库),获…...
Windows下Git Bash乱码问题解决
Windows下Git Bash乱码问题解决 缘起 个人用的电脑是Mac OS,系统和终端编码都是UTF-8,但公司给配发的电脑是Windows,装上Git Bash在使用 git commit -m "中文"时会乱码 解决 确认有以下配置 # 输入 git config --global --lis…...

HTML5 + CSS3
HTML 基础 准备开发环境 1.vscode 使用 新建文件夹 ---> 左键拖入 vscode 中 2.安装插件 扩展 → 搜索插件 → 安装打开网页插件:open in browser汉化菜单插件:Chinese 3.缩放代码字号 放大,缩小:Ctrl 加号,减号 4.设…...

NFTScan | 07.22~07.28 NFT 市场热点汇总
欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总。 周期:2024.07.22~ 2024.07.28 NFT Hot News 01/ 数据:NFT 系列 Liberty Cats 地板价突破 70000 MATIC 7 月 22 日,据 Magic Eden 数据,NFT 系列 Liberty C…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...

Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...