C++之 友元重载 以及最常用的几种友元函数
在之前的友元中就曾经讲过,我们为了去访问修改私有成员中的数据时,只能通过公有的办法去进行访问操作,非常的局限。所以C++引用了友元函数,只要加上friend关键字,C++的这个类,会自动把这个函数的权限拉到类内,这样就可以访问私有成员了。
上一篇文章,讲了重载运算符的操作。但有些运算符不能够在类内进行重载,例如输入输出的符号。下面我会详细讲,为什么不能在类内进行重载。
这里我们先假设有一个类:
A{};//功能暂且不写,知道是个类就行了
首先,普通类内重载,会自带一个this指针,指向用此函数的对象。这被称作第一操作数。
如果在定义+号的时候,实际上是并不是简单的(类对象)+(某某)亦或是(某某)+(类对象);
它实际上全部的写法应该是:
A a; //这里定义了一个对象a
a.operator+(某某); //这是全部写法,也是正常情况应该写的情况,只是我们平时简写,编译器仍然认识罢了。
a+(某某) // 这是我们平时的写法
比如你想重载<<或者>>符号,这种情况,他的第一操作符就一定不是类本身,例如:
A a;
我们不可能写成:a<<或者是a>>;我们正常的写法应该是:cin >>a;cout << a;
这里第一操作符并不是a这个对象,而是cin/cout。这是ios的输入输出的参数。
这里有人就要问了,那(类对象)+(某某);我也可以写成(某某)+(类对象);这里实际上是交换律,因为,这里类对象写的地方,并不是唯一的,可以进行交换,这种情况可以不算。
话不多说,我们使用代码来进行讲解,下面先给大家展示时间类运算符重载,作为对比,我先写类内成员函数重载,再写类外友元重载,大家可以复制下来,看看。
#include <iostream>
#include <string>
using namespace std;/*
* 1.类的成员 在类内的运算符重载函数的第一个操作数一定是类的对象
* 总结:
* 有的情况运算符必须写成非成员函数.这个函数如果需要获得类对象的私有数据,则有如下方法
* 1.可以利用交换律(前提是类已经实现该运算符的重载.1.5*t->t*1.5)
* 2.类把该函数声明为它的友元函数
* 3.类提供获取私有数据的公有方法
*
* 举例:如下
*/
class Time
{
private:int hours;//小时int minutes;//分钟
public:Time(int h = 0, int m = 0) :hours(h), minutes(m)//构造函数{}Time operator +(const Time& t)const;//重载 +,注意返回值不是引用Time operator -(const Time& t)const//重载 -{int tmp = (hours * 60 + minutes) - (t.hours * 60 + t.minutes);//分钟return Time(tmp / 60, tmp % 60);}Time operator *(double n)const;//重载 * .含义;3:40 * 3 ->11小时0分//3*3:40 不是void show() const;//提供获得时间的公有方法/* int GetHours()const{return hours;}int GetMinutes()const{return minutes;}*/
};Time Time::operator+(const Time& t)const //2:30+2:45
{return Time(hours + t.hours + (minutes + t.minutes) / 60, (minutes + t.minutes) % 60);
}Time Time::operator *(double n)const // Time * 小数
{double tmp = (hours * 60 + minutes) * n;return Time{ (int)tmp / 60,(int)tmp % 60 };
}void Time::show() const
{cout << hours << "小时," << minutes << "分钟" << endl;
}Time operator*(double n,const Time &t)//普通函数的形式重载*
{//double tmp = n * (t.hours * 60 + t.minutes);//错误,这个函数不是Time成员,不能访问它的私有// int tmp = (int)(n * (t.GetHours() * 60 + t.GetMinutes()));// return Time(tmp/60,tmp%60);return t * n;//前提:已经实现了 t*n
}int main()
{Time t1{ 2,35 };Time t2 = { 2,40 };Time t3 = t1 + t2;//t1.operator+(t2);Time t4 = t2 - t1;//t2.operator-(t1);Time t5 = t1 * 1.5;Time t6 = 1.5 * t1;//没有实现 小数*时间t3.show();t4.show();t5.show();t6.show();//t1 * 3;//t1.operator*(3);//3*t1;//3.*(t1);//在3这个int类 没有实现对Time的*重载return 0;
}
接下来,作为对比,我继续把重载输入输出的代码。
#include <iostream>
#include <string>
using namespace std;class Time
{
private:int hours;//小时int minutes;//分钟public:Time(int h = 0, int m = 0);void show() const;//void operator <<(ostream& os)//os是输出流对象的引用//{// os << hours << "小时,," << minutes << "分钟" << endl;//}friend Time operator *(double n, const Time& t);//这个是Time的友元函数friend ostream& operator <<(ostream& os, const Time& t);//这个是Time的友元函数//实现 >> 运算符重载 istreamfriend istream& operator >>(istream& is, Time& t);
};Time::Time(int h, int m)
{hours = h;minutes = m;
}void Time::show() const
{cout << hours << "小时," << minutes << "分钟" << endl;
}Time operator *(double n, const Time& t)
{int tmp = (int)(n * (t.hours * 60 + t.minutes));return Time(tmp/60,tmp%60);
}ostream & operator <<(ostream& os, const Time& t)//os不加const,需要把数据写入到输出流
{os << t.hours << "小时,," << t.minutes << "分钟" << endl;return os;
}istream& operator >>(istream& is, Time& t)
{return is >> t.hours >> t.minutes;
}int main()
{Time t1 = { 2,35 };Time t2 = { 2,40 };Time t3 = 1.5*t1; //第一个操作数不是类对象,所以只能是非成员函数//t3.show();//t3 << cout; //可以作为类成员函数的,但不能理解cout << t3;//这个不能调用t3的成员函数,但我们需要cout << t1 << t2;cin >> t1; //5 30cout << t1;//5小时,30分钟// cout << t3 ;//错误,没有实现如何 cout<< Time的对象//cout 是 ostream类对象 ; cin是istream类对象return 0;
}
每日金句:
一步一行,便无惧陷入泥沼!
---------------银枝

相关文章:
C++之 友元重载 以及最常用的几种友元函数
在之前的友元中就曾经讲过,我们为了去访问修改私有成员中的数据时,只能通过公有的办法去进行访问操作,非常的局限。所以C引用了友元函数,只要加上friend关键字,C的这个类,会自动把这个函数的权限拉到类内&a…...
动态规划(3)——dp多状态问题Ⅰ
题一.按摩师(LeetCode) 题目描述 一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集…...
在Mac电脑上安装adb环境
当你在命令行输入 adb version 或adb devices, 报错:zsh: command not found: adb ,那么说明你的 Mac 上没有安装 ADB(Android Debug Bridge),或者它没有添加到你的路径中。你可以按照以下步骤安装和配置 ADBÿ…...
分糖果C++
题目: 样例解释: 样例1解释 拿 k20 块糖放入篮子里。 篮子里现在糖果数 20≥n7,因此所有小朋友获得一块糖; 篮子里现在糖果数变成 13≥n7,因此所有小朋友获得一块糖; 篮子里现在糖果数变成 6<n7…...
Spring中如何为静态变量注入值
在 Spring 中,如果使用 Value 注解注入值,不能将其应用于 static 字段。Spring 只能为实例变量注入值,不能直接对静态变量进行注入。 使用 PostConstruct 初始化: 如果确实需要在静态上下文中使用该值,可以使用 Post…...
HTML5实现唐朝服饰网站模板源码
文章目录 1.设计来源1.1 网站首页-界面效果1.2 唐装演变-界面效果1.3 唐装配色-界面效果1.4 唐装花纹-界面效果1.5 唐装文化-界面效果 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板,程序开发,在线开发,在线沟通 作者:xcL…...
ESXI识别USB设备
步骤: 插入usb设备到服务器。关闭虚拟机,添加USB控制器,根据U盘选择usb 3.0控制器,再添加usb设备如果usb设备灰色,进入主机打开SSH。使用xshell进行连接,运行以下命令: ESXI识别USB设备 - 插入…...
视频美颜SDK与直播美颜工具API是什么?计算机视觉技术详解
今天,小编将深入探讨视频美颜SDK与直播美颜工具API的概念及其背后的计算机视觉技术。 一、视频美颜SDK的概念 视频美颜SDK是一套用于开发实时美颜效果的工具集,开发者可以利用它在视频流中实现面部特征的优化。这些SDK通常提供了一系列功能,…...
not exist 解决一对多 场景 条件过滤问题
场景: 现在存在一对多关系,蓝色的盒子装的篮球,黄的的盒子装的黄球, 黑色的盒子 (模拟工作类似场景) boxIdballId蓝盒ID-15蓝盒ID-16蓝盒ID-17黄盒ID-212黄盒ID-215黄盒ID-216黑盒ID-38黑盒ID-39 需求&a…...
解决$‘r‘ command not found或者文件夹显示’tvsf 33‘$‘r‘
问题现象: 某客户反馈在执行脚本的时候文件夹显示存在问题,如下图: 但是脚本文件中的内容并没有\r字符,如下图: 也有客户反馈如下: 问题分析: $\r’是回车符的转义表示。在Unix和Linux系统中,回车符是一个不可见的控制字符,它通常用于文本文件中的行结尾。以上…...
linux:详解nohup命令
在 UNIX 和类 UNIX 操作系统(如 Linux 和 macOS)中,nohup 意图为后台运行且免疫挂断信号的命令,用于在用户注销(logout)或终端关闭后继续运行相应的进程。 基本语法 启动进程 nohup [COMMAND] [ARG...] …...
负载箱:充电桩测试利器
RCD负载箱是用于测试和验证电气设备在故障状态下的性能的设备。它可以模拟真实的负载情况,从而帮助工程师和技术人员对设备进行准确的检测和维护。此外,RCD负载箱也是一种重要的安全保护设备,主要用于防止电路中的漏电现象引发的事故。它通常…...
Ubuntu 开机自启动 .py / .sh 脚本,可通过脚本启动 roslaunch/roscore等
前言 项目中要求上电自启动定位程序,所以摸索了一种 Ubuntu 系统下开机自启动的方法,开机自启动 .sh 脚本,加载 ROS 环境的同时启动 .py 脚本。在 . py 脚本中启动一系列 ROS 节点。 一、 .sh 脚本的编写 #!/bin/bash # gnome-terminal -- …...
RabbitMQ 消息队列:生产者与消费者实现详解
在分布式系统中,消息队列(Message Queue, MQ)是一种重要的组件,用于解耦系统、异步处理任务以及实现系统间的通信。RabbitMQ 是一个流行的开源消息代理软件,它实现了高级消息队列协议(AMQP)。在…...
vue3项目中组件切换不起作用
以下这种方式写页面中组件切换,不起作用。 <component :is"steps[compIndex].comp" />解决:使用shallowReactive或者shallowRef把对应的组件名称重新定义下。 <component :is"compNames[steps[compIndex].comp]" /> &…...
YOLOv11改进策略【损失函数篇】| Slide Loss,解决简单样本和困难样本之间的不平衡问题
一、本文介绍 本文记录的是改进YOLOv11的损失函数,将其替换成Slide Loss,并详细说明了优化原因,注意事项等。Slide Loss函数可以有效地解决样本不平衡问题,为困难样本赋予更高的权重,使模型在训练过程中更加关注困难样…...
动静态库(Linux)
文章目录 前言一、静态库二、动态库三、深入理解动态库总结 前言 我们之前用过c语言的库.Linux中默认的都是使用动态库,如果想要使用静态库,就必须加上-static选项。默认都是安装的动态库,系统中一般没有静态库,如果要使用&#…...
51单片机和ARM单片机的区别
在嵌入式系统设计与应用中,单片机作为核心控制单元,扮演着至关重要的角色。其中,51单片机和ARM单片机作为两种常见的单片机类型,各自具有独特的特点和优势。本文将从多个维度深入探讨这两种单片机的区别,以便读者更好地…...
[Day 81] 區塊鏈與人工智能的聯動應用:理論、技術與實踐
區塊鏈在食品安全中的應用 前言 食品安全一直是全球關注的問題,隨著全球供應鏈的複雜性增加,追踪食品從生產到消費的過程變得愈發困難。區塊鏈技術以其去中心化、不可篡改的特性,為食品安全提供了可靠的解決方案。在這篇文章中,…...
flac格式怎么转mp3?关于flac转为MP3的方法介绍
flac格式怎么转mp3?MP3格式经过压缩,相较于flac文件,显著减小了文件体积。这一特点使得音乐的存储和传输更加便捷,尤其适合移动设备以及存储空间有限的场景。由于MP3文件体积较小,分享音乐变得非常简单,无论…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...
【若依】框架项目部署笔记
参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作: 压缩包下载:http://download.redis.io/releases 1. 上传压缩包,并进入压缩包所在目录,解压到目标…...
理想汽车5月交付40856辆,同比增长16.7%
6月1日,理想汽车官方宣布,5月交付新车40856辆,同比增长16.7%。截至2025年5月31日,理想汽车历史累计交付量为1301531辆。 官方表示,理想L系列智能焕新版在5月正式发布,全系产品力有显著的提升,每…...
