C++ 赋值运算重载,const成员,取地址及const取地址操作符重载

C++ 赋值运算重载,const成员,取地址及const取地址操作符重载

  • 1. 赋值运算符重载
    • 1.1 运算符重载
    • 1.2 赋值运算符重载
    • 1.3 前置++/--和后置++/--重载
  • 2. const成员
  • 3. 取地址及const取地址操作符重载

在这里插入图片描述

所属专栏:C“嘎嘎" 系统学习❤️
🚀 >博主首页:初阳785❤️
🚀 >代码托管:chuyang785❤️
🚀 >感谢大家的支持,您的点赞和关注是对我最大的支持!!!❤️
🚀 >博主也会更加的努力,创作出更优质的博文!!❤️
🚀 >关注我,关注我,关注我,重要的事情说三遍!!!!!!!!❤️

1. 赋值运算符重载

1.1 运算符重载

  • 我们知道,两个内置类型之间是可以进行适合的运算的,比如两个整形是可以进行加减乘除的,也可以进行比较两个数的大小关系,以此相对应char,double类型的也是可以进行类似的操作的。但是这些都是仅仅有限于内置类型,如果变成了自定义类型呢?自定义类型也可以做到像自定义类型一样的操作吗?所以C++中为了解决这个方法,有了运算符重载的概念。

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其
返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)

  • 注意:
    1.不能通过连接其他符号来创建新的操作符:比如operator@
    2.重载操作符必须有一个类类型参数
    3.用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
    4.作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
    4..* :: sizeof ?: . 注意以上5个运算符不能重载。这个经常在笔试选择题中出
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// bool operator==(Date* this, const Date& d2)// 这里需要注意的是,左操作数是this,指向调用函数的对象bool operator==(const Date& d2) //操作数opertor{return _year == d2._year&& _month == d2._month&& _day == d2._day;}
private:int _year;int _month;int _day;
};int main()
{Date d1;Date d2;bool ret = d1 == d2; // ——> 本质是d1.operato==(d2);(operato==整体看作是一个函数名),但是做了优化之后就可以直接使用if (ret){cout << "d1 == d2" << endl;}else{cout << "d1 != d2" << endl;}return 0;
}

1.2 赋值运算符重载

1.赋值运算符重载格式

  • 参数类型:const T&,传递引用可以提高传参效率
  • 返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
  • 检测是否自己给自己赋值
  • 返回*this :要复合连续赋值的含义
class Date
{
public:Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}
private:int _year;int _month;int _day;
};int main()
{Date d1;Date d2(2023, 10, 28);d1 = d2;//本质上是——> d1.operator=(d2)return 0;
}
  1. 赋值运算符只能重载成类的成员函数不能重载成全局函数
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}int _year;int _month;int _day;
};
// 赋值运算符重载成全局函数,注意重载成全局函数时没有this指针了,需要给两个参数
Date& operator=(Date& left, const Date& right)
{if (&left != &right){left._year = right._year;left._month = right._month;left._day = right._day;}return left;
}int main()
{Date d1;Date d2(2023, 10, 28);d1 = d2;//本质上是——> d1.operator=(d2)return 0;
}

我们在看一段代码:

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}int _year;int _month;int _day;
};int main()
{Date d1;Date d2(2023, 10, 28);d1 = d2;//这里没有进行重载,但是也是可以的return 0;
}
  • 原因:赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现
    一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故赋值
    运算符重载只能是类的成员函数

在这里插入图片描述

3.用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。注
意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符
重载完成赋值。这一点和前面的拷贝构造是一样的道理。

  • 那么有小伙伴就会问了,既然我们不写显示实现运算符重载编译器会帮我们实现重载的效果,那我们为什么还要自己再写一个呢?这个时候我们可以回顾一下我们之前的拷贝构造,在我们没有涉及到资源管理的时候,拷贝构造是正常的,但是一旦我们malloc一块空间的时候就出问题了,而这里也是一样的,起始赋值运算是一种特殊的拷贝构造。

1.3 前置++/–和后置++/–重载

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// 前置++:返回+1之后的结果// 注意:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率Date& operator++(){_day += 1;return *this;}
private:int _year;int _month;int _day;
};
  • 上面是前置++ 的运算符重载操作。
    现在小伙伴们想一想后置++怎么办呢?
    首先就是他的重载格式是什么样的?
    返回类型是什么?
    因为我们的后置++ 的规则是先使用后++的,也就是说只有在一条语句结束后才会++。
    那么我们因该怎么实现呢?

在C++中为了区分前置和后置,C++中用占位参数来区分前置和后置,没有占位参数的是前置,又占位参数的是后置,并规定占位参数的类型是int。

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// 后置++:// 前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载// C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器自动传递// 注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this + 1// 而temp是临时对象,因此只能以值的方式返回,不能返回引用Date operator++(int){Date temp(*this);//先保存原先的值_day += 1;//再进行加加return temp;//最后返回保存的值}
private:int _year;int _month;int _day;
};

2. const成员

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数
隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}private:int _year;int _month;int _day;
};int main()
{Date d1(2023, 11, 1);d1.Print();return 0;
}

我们看这串代码是没什么问题的,但是如果我用const修饰一下d1呢?

const Date d1(2023, 11, 1);
d1.Print();

这个时候还能通过吗?

这个时候就会报错啦,因为存在权限放大:
原本是:
在这里插入图片描述

  • 但是我们对d1用const修饰的时候,我们传过去的类型是const d1是不可修改的,但是我们函数接受的参数类型却不是const不可修改的类型,所以这里就有权限放大的问题。
    解决这个问题的办法也很简单,就是把我我们的形参也改成const修饰的参数:即const Date* const this
    但是问题是const加在那里,C++规定成员函数用const修饰加在形参列表之后:
    在这里插入图片描述

我们在看一下这段代码:

class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}void Print() const{cout << _year << "/" << _month << "/" << _day << endl;}private:int _year;int _month;int _day;
};int main()
{const Date d1(2023, 11, 1);d1.Print();Date d2(2023, 11, 1);d2.Print();return 0;
}
  • 这里的d2会不会出错呢?
    分析一下,我们的成员函数是用const修饰的,而d2却没有使用const修饰的。
    但是这里是不会报错的,因为这里是属于权限的缩小。
    C++规定,权限允许权限的平移和缩小的。
    所以既然权限允许缩小的话,这里建议小伙伴们在写成员函数的时候,成员对象不可修改尽量用const修饰,这样跟更能保证代码的容错率,因为即使成员对象没有用const修饰,有权限缩小这特性还是可以通过的。

3. 取地址及const取地址操作符重载

  • 这两个默认成员函数一般不用重新定义 ,编译器默认会生成。
class Date
{
public:Date* operator&(){return this;}const Date* operator&()const{return this;}
private:int _year; // 年int _month; // 月int _day; // 日
};int main()
{Date d1;Date d2;cout << &d1 << endl;cout << &d2 << endl;return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/178420.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内置对象和方法、前端基础之BOM和DOM

内置对象和方法 RegExp对象 // 定义正则表达式两种方式 var reg1 new RegExp("^[a-zA-Z][a-zA-Z0-9]{5,11}"); var reg2 /^[a-zA-Z][a-zA-Z0-9]{5,9}$/;// 正则校验数据 reg1.test(jason666) reg2.test(jason666)/*第一个注意事项&#xff0c;正则表达式中不能有…

多输入多输出 | Matlab实现k-means-ELM(k均值聚类结合极限学习机)多输入多输出组合预测

多输入多输出 | Matlab实现k-means-ELM&#xff08;k均值聚类结合极限学习机&#xff09;多输入多输出组合预测 目录 多输入多输出 | Matlab实现k-means-ELM&#xff08;k均值聚类结合极限学习机&#xff09;多输入多输出组合预测预测效果基本描述程序设计参考资料 预测效果 基…

服务器数据恢复-VSAN环境下ESXI虚拟机无法访问的数据恢复方案

一、用户信息&#xff1a; 广东某单位 二、数据恢复环境&#xff1a; 主机操作系统&#xff1a;ESXI 分区类型&#xff1a;VSAN 存储介质清单 &#xff1a;一共8台服务器节点&#xff0c;每节点2个磁盘组&#xff0c;其中1个磁盘组配置1块SSD固态硬盘&#xff0c;4块1.2T机…

Docker安装部署[8.x]版本Elasticsearch+Kibana+IK分词器

文章目录 Docker安装部署elasticsearch拉取镜像创建数据卷创建网络elasticsearch容器&#xff0c;启动&#xff01;踩坑&#xff1a;虚拟机磁盘扩容 Docker安装部署Kibana拉取镜像Kibana容器&#xff0c;启动&#xff01; 安装IK分词器安装方式一&#xff1a;直接从github上下载…

人工智能基础_机器学习011_梯度下降概念_梯度下降步骤_函数与导函数求解最优解---人工智能工作笔记0051

然后我们来看一下梯度下降,这里先看一个叫 无约束最优化问题,,值得是从一个问题的所有可能的备选方案中选最优的方案, 我们的知道,我们的正态分布这里,正规的一个正态分布,还有我们的正规方程,他的这个x,是正规的,比如上面画的这个曲线,他的这个x,就是大于0的对吧,而现实生活…

论文阅读 - Detecting Social Bot on the Fly using Contrastive Learning

目录 摘要&#xff1a; 引言 3 问题定义 4 CBD 4.1 框架概述 4.2 Model Learning 4.2.1 通过 GCL 进行模型预训练 4.2.2 通过一致性损失进行模型微调 4.3 在线检测 5 实验 5.1 实验设置 5.2 性能比较 5.5 少量检测研究 6 结论 https://dl.acm.org/doi/pdf/10.1145/358…

nodejs express vue 点餐外卖系统源码

开发环境及工具&#xff1a; nodejs&#xff0c;vscode&#xff08;webstorm&#xff09;&#xff0c;大于mysql5.5 技术说明&#xff1a; nodejs express vue elementui 功能介绍&#xff1a; 用户端&#xff1a; 登录注册 首页显示搜索菜品&#xff0c;轮播图&#xf…

Diango项目-简易个人博客项目

项目实现功能 在admin后台自定义添加上传文档。对展示在首页的文章分页显示。在首页点击文章的阅读全文按钮可进入该文章全文详情页进行浏览。对文章实现了内容分类何以发布时间进行归档分类。使用django的whoose搜索引擎对全文实现内容的搜索。 项目涉及技术 Mysql Djan…

【设计模式】第10节:结构型模式之“组合模式”

一、简介 组合模式&#xff1a;将一组对象组织成树形结构&#xff0c;将单个对象和组合对象都看做树中的节点&#xff0c;以统一处理逻辑&#xff0c;并且它利用树形结构的特点&#xff0c;递归地处理每个子树&#xff0c;依次简化代码实现。使用组合模式的前提在于&#xff0…

ts 简易封装 axios,统一 API

文章目录 为什么要封装目标文件结构封装通用请求方法获得类型提示http 方法文件上传使用示例实例化post 请求类型提示文件上传 总结完整代码&#xff1a; 为什么要封装 axios 本身已经很好用了&#xff0c;看似多次一举的封装则是为了让 axios 与项目解耦。比如想要将网络请求…

【广州华锐互动】风景区规划VR虚拟现实教学系统

风景区规划VR虚拟现实教学系统是一种新兴的教学工具&#xff0c;它可以通过虚拟现实技术&#xff0c;为学生提供一种沉浸式的、实时的、全方位的景区规划体验。 在风景区规划VR虚拟现实教学系统中&#xff0c;学生可以通过虚拟现实技术&#xff0c;实时地与景区进行交互。他们可…

Spring - 手写模拟Spring底层原理

手写Spring 定义配置类AppConfig ComponentScan("com.spring.zsj") public class AppConfig {Beanpublic ApplicationListener applicationListener() {return new ApplicationListener() {Overridepublic void onApplicationEvent(ApplicationEvent event) {System…

【WinForm详细教程五】WinForm中的MenuStrip 、ContextMenuStrip 、ToolStrip、StatusStrip控件

文章目录 1.MenuStrip2.ContextMenuStrip3.ToolStrip4.StatusStrip 1.MenuStrip MenuStrip作为一个容器可以包含多个菜单项。MenuStrip 的重要属性包括&#xff1a; Name&#xff1a;菜单的名字Dock&#xff1a;菜单的停靠位置Items&#xff1a;菜单项的集合 ToolStripMenuI…

前端接口请求支持内容缓存和过期时间

前端接口请求支持内容缓存和过期时间 支持用户自定义缓存时间&#xff0c;在规则时间内读取缓存内容&#xff0c;超出时间后重新请求接口 首先封装一下 axios&#xff0c;这一步可做可不做。但是在实际开发场景中都会对 axios 做二次封装&#xff0c;我们在二次封装的 axios …

vue3中解析地址(address-parse插件的使用)

1.安装 npm install address-parse --save 2.使用 // 引入address-parse import AddressParse, { AREA, Utils } from "address-parse";const adressValue ref([])const getResolutionContent () > {const [result] AddressParse.parse(EnterpriseSalesDetai…

JAVA虚拟机-第2章 Java自动内存管理-异常实践

Java堆溢出 堆的参数设置&#xff1a;将堆的最小值-Xms参数与最大值-Xmx参数设置 public class HeapOOM {static class OOMObject {}public static void main(String[] args) {List<OOMObject> list new ArrayList<OOMObject>();while (true) {list.add(new OO…

JTS: 13 Polygonizer 多线合成面

这里写目录标题 版本代码 版本 org.locationtech.jts:jts-core:1.19.0 链接: github 代码 线段 生成之后的面 public class GeometryPolygonization {private static final GeometryFactory geometryFactory new GeometryFactory();private static final Logger LOGGER …

陪诊系统|挂号陪护搭建二开陪诊师入驻就医小程序

我们的陪诊小程序拥有丰富多样的功能&#xff0c;旨在最大程度满足现代人的需求。首先&#xff0c;我们采用了智能排队系统&#xff0c;通过扫描二维码获取排号信息&#xff0c;让您从繁琐的排队过程中解放出来。其次&#xff0c;我们提供了多种支付方式&#xff0c;不仅可以实…

管理类联考——数学——汇总篇——知识点突破——代数——函数、方程——记忆

文章目录 考点记忆/考点汇总——按大纲 整体局部 本篇思路&#xff1a;根据各方的资料&#xff0c;比如名师的资料&#xff0c;按大纲或者其他方式&#xff0c;收集/汇总考点&#xff0c;即需记忆点&#xff0c;在通过整体的记忆法&#xff0c;比如整体信息很多&#xff0c;通常…

python线程(进程子单位)

进程是由CPU给分配的执行单元&#xff0c;比较消耗空间和内存 创建、使用线程 import threading# 进程 # 线程 from time import sleepdef download():list1 ["girl.png", "boy.png", "child.png"]for l in list1:print(l)sleep(1.5)print(&qu…