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

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;
}

在这里插入图片描述

相关文章:

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

C 赋值运算重载&#xff0c;const成员&#xff0c;取地址及const取地址操作符重载 1. 赋值运算符重载1.1 运算符重载1.2 赋值运算符重载1.3 前置/--和后置/--重载 2. const成员3. 取地址及const取地址操作符重载 所属专栏&#xff1a;C“嘎嘎" 系统学习❤️ &#x1f680;…...

嵌入式Linux系统的闪存设备和文件系统学习纪要

嵌入式Linux系统的闪存设备和文件系统学习纪要 Linux下的文件系统结构如下&#xff1a; NAND Flash 是一种非易失性存储器&#xff08;Non-Volatile Memory&#xff09;&#xff0c;常用于闪存设备和固态硬盘&#xff08;SSD&#xff09;中。以下是几种常见的 NAND Flash 种类&…...

android 8.1 disable unsupported sensor

如果device不支持某种sensor,可以在android/frameworks/base/core/java/android/hardware/SystemSensorManager.java里将其disabled掉。以disable proximity sensor为例。 public SystemSensorManager(Context context, Looper mainLooper) {synchronized(sLock) {if (!sNativ…...

二、类与对象(一)

1 面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。以洗衣服为例&#xff0c;通常洗衣服会经历以下过程&#xff1a; 而C是基于面向对象的&#xff0c;关注的是对象&#xff0c…...

写给所有的程序员,或者努力生活的你。

朋友们&#xff0c;好好休息&#xff0c;意味着好好锻炼&#xff0c;好好睡觉&#xff0c;好好学习&#xff0c;学习可以是功利的&#xff0c;需要有规划的&#xff0c;有执行能力&#xff0c;有反馈奖励机制的&#xff0c;也可以无用之用方为大用&#xff08;比如take shit的时…...

pytorch 笔记:GRU

1 介绍 对于输入序列中的每个元素&#xff0c;每一层都计算以下函数&#xff1a; ht​ 是t时刻 的隐藏状态xt​ 是t时刻 的输入ht−1​ 是 t-1时刻 同层的隐藏状态或 0时刻 的初始隐藏状态rt​,zt​,nt​ 分别是重置门、更新门和新门。σ 是 sigmoid 函数∗ 是 Hadamard 乘积。…...

Kubernetes - Ingress HTTP 升级 HTTPS 配置解决方案(新版本v1.21+)

之前我们讲解过 Kubernetes - Ingress HTTP 搭建解决方案&#xff0c;并分别提供了旧版本和新版本。如果连 HTTP 都没搞明白的可以先去过一下这两篇 Kubernetes - Ingress HTTP 负载搭建部署解决方案_放羊的牧码的博客-CSDN博客Kubernetes - Ingress HTTP 负载搭建部署解决方案…...

Verilog:写流水灯时遇到的问题

module flow_led(input sys_clk, //系统时钟50Mhz 周期0.02nsinput sys_rst_n, //系统异步复位&#xff0c;低电平有效output reg [3:0] led ); reg [24:0] cnt;//计数器计时0.5s250000000*0.02ns always(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)cnt <…...

操作系统第四章-存储器管理

4.1 内存的基本知识 4.1.1 逻辑地址和物理地址 逻辑地址又称为相对地址 物理地址又称为绝对地址 一. 逻辑地址 内存中有多个进程,相对地址是相对于进程的起始地址而言的地址. 二.物理地址 绝对地址是在整个内存下的地址 4.2 程序的装入和链接 引入:用户程序要在系统中运…...

org.springframework.cloud:spring-cloud-starter-openfeign:jar is missing详解

openfeign无法导入的问题 我感觉最近带的好几个新人在搭建springCloud基础框架的时候&#xff0c;会犯一个非常小的错误&#xff0c;导致进度卡住了。 这个错误就是Feign导入的错误&#xff1a; ‘dependencies.dependency.version’ for org.springframework.cloud:spring-c…...

Netty第一部

一、select和epoll原理分析 外设设备网卡、鼠标、键盘等通过总线写到内存中&#xff0c;中间就有DMA拷贝&#xff0c;操作系统怎么知道内存中有数据了&#xff0c;这就需要操作系统通过中断机制确定&#xff0c;如果有中断信号过来&#xff0c;cpu会首先打断用户程序执行&…...

【设计模式】第11节:结构型模式之“装饰器模式”

一、简介 装饰器模式主要解决继承关系过于复杂的问题&#xff0c;通过组合来替代继承。它主要的作用是给原始类添加增强功能。这也是判断是否该用装饰器模式的一个重要的依据。除此之外&#xff0c;装饰器模式还有一个特点&#xff0c;那就是可以对原始类嵌套使用多个装饰器。…...

Spire.doc读取模板文档,并在书签处插入内容

在书签位置插入文字 //加载模板文档 Document document new Document(Server.MapPath("~/File/评价结果.doc")); //创建书签导航器 BookmarksNavigator bn new BookmarksNavigator(document); //添加一个section到文档 Section newSec document.AddSection(); …...

性能测试实施流程,5个阶段给老板安排的明明白白!

性能测试分为5个阶段&#xff0c;分别是【需求调研阶段】→【测试准备阶段】→【测试执行阶段】→【测试报告阶段】→【测试总结阶段】。 1、需求调研阶段 需求调研分为两个步骤进行&#xff1a;需求调研、需求分析 需求调研 需求调研工作由性能测试实施人员牵头负责&#…...

【教程】R语言生物群落(生态)数据统计分析与绘图

查看原文>>>R语言生物群落&#xff08;生态&#xff09;数据统计分析与绘图实践 暨融合《R语言基础》、《tidyverse数据清洗》、《多元统计分析》、《随机森林模型》、《回归及混合效应模型》、《结构方程模型》、《统计结果作图》七合一版本方案 R 语言作的开源、自…...

数据库-用户权限管理

创建用户&#xff1a; create user testlocalhost identified by 123456; create user 创建用户的固定开头 testlocalhost test为用户名&#xff0c; localhost:新建用户可以在哪些主机上登录&#xff0c;即使可以使用IP地址&#xff0c;网段主机名都可以 identified by 1…...

十一、W5100S/W5500+RP2040树莓派Pico<ARP 地址解析>

文章目录 1 前言2 简介2 .1 什么是ARP&#xff1f;2.2 ARP的优点2.3 ARP工作原理2.4 ARP应用场景 3 WIZnet以太网芯片4 ARP网络设置示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链接 1 前言 随着网络安全越来越受到重…...

可以直接在线制作电子画册的网站

​随着互联网技术的发展&#xff0c;越来越多的人开始使用在线工具来制作电子画册。今天&#xff0c;小编就来介绍一款可以直接在线制作电子画册的网站&#xff0c;让你的电子画册更加精美、个性化和实用。 1.首先点击FLBOOK在线制作制作电子杂志平台 2.点击开始制作&#xff0…...

SortableJS:vuedraggable实现元素拖放排序

文档&#xff1a;https://sortablejs.github.io/Sortable/github&#xff1a;https://github.com/SortableJS/SortableVue2: https://github.com/SortableJS/Vue.DraggableVue3: https://github.com/SortableJS/vue.draggable.nextnpm https://www.npmjs.com/package/vuedragga…...

跟着Nature Communications学作图:纹理柱状图+添加显著性标签!

&#x1f4cb;文章目录 复现图片设置工作路径和加载相关R包读取数据集数据可视化计算均值和标准差方差分析组间t-test 图a可视化过程图b可视化过程合并图ab 跟着「Nature Communications」学作图&#xff0c;今天主要通过复刻NC文章中的一张主图来巩固先前分享过的知识点&#…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

C++--string的模拟实现

一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现&#xff0c;其目的是加强对string的底层了解&#xff0c;以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量&#xff0c;…...