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

C++——友元函数

如下是一个日期类:

class Date
{
public:Date(int year = 2023, int month = 10, int day = 1){_year = year;_month = month;_day = day;if (_month < 1 || month > 12 || _day < 1 || _day > GetMonthDay(_year, _month)){cout << "日期不规范" << endl;//exit(-1);  终止程序}}//拷贝构造函数Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}void print() const //const 放在这里,指的是this指针为const Date*类型,这样就可以让const Date类型进行print了{cout << _year << "/" << _month << "/" << _day << endl;}int GetMonthDay(int year, int month)//获取某面某月的天数{//加static,可以省去每次访问时都开辟数组空间。static int MonthArray[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if ((month == 2) && ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)))return 29;return MonthArray[month];}//赋值运算符//返回类型为Date,支持连续赋值Date& operator=(const Date& d){_year = d._year;_month = d._month;_day = d._day;return *this;//*this出了函数还在,就可以使用引用返回。}
private:int _year;int _month;int _day;
};

假设我们不使用日期类的print函数,通过<<符号重载,能不能实现日期类的打印?

然后使用:

发现这时无法使用的

原因:

这个内部函数的第一个参数,也就是<<左边的操作数,是this,为日期类

第二个参数为<<右侧的操作数out,为ostream类

而我们调用的时候,cout << d1,左侧写的是ostream类,右侧写的是日期类,顺序发生了错误。

只要我们将顺序调换就可以正常使用了,但是这不太符合我们平时的使用习惯

要想手动设置两个参数的位置,就不能将其实现为内部的成员函数,而是类外部的函数:

但是,这样,类内部的private参数就不能访问了

这里的解决方法就是实现这个类的各种参数的set和get方法,但是这样有点麻烦

还有一种解决方式,就涉及到了友元。

友元:

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以要尽可能减少使用。

友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加上friend关键字。

如下:

【BTW】:为了实现能够连续调用,返回类型改成了ostream类型

友元声明可以放在类内的任何地方。

这样就可以实现了<<的重载了。

同理,实现>>的重载,总体如下:

相关文章:

  • wpf 命令概述
  • 【3】Spring Boot 3 集成mybatis-plus+druid+mysql
  • 竞赛 题目:基于LSTM的预测算法 - 股票预测 天气预测 房价预测
  • 【算法练习Day47】两个字符串的删除操作编辑距离
  • ElasticSearch7.x - HTTP 操作 - 查询文档操作
  • C语言从入门到精通之【常量和C预处理器】
  • spring-cloud之consul
  • 修复img实际有正确的链接,但是不显示 (chrome 插件保存的html)--google镜像chatgpt
  • 初识RabbitMQ - 安装 - 搭建基础环境
  • 贝锐向日葵如何实现无人值守远程控制?
  • 1234444444
  • MySQL库的操作『增删改查 ‖ 编码问题 ‖ 备份与恢复』
  • redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
  • Flink之Catalog
  • Java安全架构 JCA、JCE、JSSE、JAAS
  • 分享的文章《人生如棋》
  • C++类的相互关联
  • Effective Java 笔记(一)
  • jdbc就是这么简单
  • JS基础之数据类型、对象、原型、原型链、继承
  • JS题目及答案整理
  • Making An Indicator With Pure CSS
  • Markdown 语法简单说明
  • opencv python Meanshift 和 Camshift
  • orm2 中文文档 3.1 模型属性
  • PaddlePaddle-GitHub的正确打开姿势
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • v-if和v-for连用出现的问题
  • 从零开始学习部署
  • 将 Measurements 和 Units 应用到物理学
  • 聊聊flink的BlobWriter
  • 软件开发学习的5大技巧,你知道吗?
  • 设计模式走一遍---观察者模式
  • 时间复杂度与空间复杂度分析
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 算法-插入排序
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 想写好前端,先练好内功
  • 赢得Docker挑战最佳实践
  • 《天龙八部3D》Unity技术方案揭秘
  • Java数据解析之JSON
  • Java性能优化之JVM GC(垃圾回收机制)
  • ​Spring Boot 分片上传文件
  • #pragma once
  • $.ajax中的eval及dataType
  • $jQuery 重写Alert样式方法
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • (ZT)出版业改革:该死的死,该生的生
  • (二)WCF的Binding模型
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (实战篇)如何缓存数据
  • (一)Neo4j下载安装以及初次使用
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)Scala的“=”符号简介