【C++】类和对象(中下)

  前言:

        上一篇文章,我们了解了类的默认成员函数——构造函数、析构函数、拷贝构造函数,这篇我们让我们接着了解。

一、赋值运算符重载:

1.运算符重载:

        C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也就是说它跟普通的函数一样具有返回值类型,安徽念书名字以及参数列表。

 函数名字:关键字(operator)后面接需要重载的运算符符号;

函数原型:返回值类型operator操作符(参数列表)。

ps:

①.只能在原有的运算符基础上重载,不能通过连接其他符号来创建新的操作符,比如:operator@、operator#等等都不行;

②.重载操作符必须有一个类类型参数;

③用于内置类型的运算符,其含义不能改变,例如:内置的整形+,不能改变其含义;

④作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this指针。

*::sizeof?: , . 这五个操作符不能重载。

class Date
{
public:Date(int year=2023,int month=9,int day=15){_year=year;_month=month;_day=day;}    
public:
//这里因为运算符重载成全局的需要成员函数是公有的,后期可以用友元解决,或者重载成成员函数;int _year;int _month;int _day;
};
bool opprator==(const Date& d1,const Date& d2)
{return d1._year=d2._year&&d1._month==d2._month&&d1._day==d2._day;
}void Test()
{Date d1(2002,09,21);Date d2;cout<<(d1==d2)<<endl;
}

在类里面实现:

class Date
{
public:Date(int year=2023,int month=9,int day=15){_year=year;_month=month;_day=day;}    bool opprator==(const Date& d2){return _year=d2._year&&_month==d2._month&&_day==d2._day;}private:int _year;int _month;int _day;
};void Test()
{Date d1(2002,09,21);Date d2;cout<<(d1==d2)<<endl;
}

2.赋值运算符重载:

Ⅰ.赋值运算符重载格式:

参数类型:const T&,传递引用可以提高传参效率;

返回值类型:T&,返回引用可以提高返回效率,有返回值目的是为了支持连续赋值;

检测是否给自己赋值;

返回*this。

class Date
{
public:Date(int year=2023,int month=9,int day=15){_year=year;_month=month;_day=day;}    bool oprator==(const Date& d2){return _year=d2._year&&_month==d2._month&&_day==d2._day;}Date& oprator=(const Date& d){if(this!=&d){_year=d._year;_month=d.month;_day=d._day;}return *this;}private:int _year;int _month;int _day;
};

Ⅱ赋值运算符只能重载成类的成员函数不能重载成全局函数:

class Date
{
public:Date(int year=2023,int month=9,int day=15){_year=year;_month=month;_day=day;}    bool oprator==(const Date& d2){return _year=d2._year&&_month==d2._month&&_day==d2._day;}private:int _year;int _month;int _day;
};
Date& oprator=(const Date& d1,const Date& d2){if(&d2=&d1){d1._year=d2._year;d1._month=d2.month;d1._day=d2._day;}return d1;}
void Test()
{Date d1(2002,09,21);Date d2;cout<<(d1==d2)<<endl;
}

        上面这段代码会编译失败:error C2801:“operator=”必须是非静态成员。

原因:赋值运算符如果不显示实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,所以赋值运算符只能是类成员函数。

编译器生成的默认赋值运算符重载是以值的方式逐字节拷贝

Ⅲ.默认赋值运算符重载

        上面我们讲到认编译器生成的默认赋值运算符重载是以值的方式逐字节拷贝。对于日期类来说,逐字节拷贝可以完成相应功能,但是有些情况逐字节拷贝无法完成,所以就需要深拷贝,现在我们来看看深拷贝的情况。

class Stack
{
public:Stack(size_t capacity = 10){_array = (int*)malloc(capacity * sizeof(int));if (nullptr == _array){perror("llmalloc申请空间失败");return;}_size = 0;_capacity = capacity;}void Push(const int& data){//检查需要扩容,但这只是演示一下深拷贝情况,所以就不写了_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}
private:int* _array;size_t _size;size_t _capacity;
};int main()
{Stack s;s.Push(1);s.Push(2);s.Push(3);Stack s1;s1 = s;return 0;
}

上述代码会造成两个问题:

①指向同一块空间,但s改变的时候s1也会跟着改变。

②当程序结束的时候会调用两次析构函数,同一块空间析构两次,这也是导致程序奔溃的主要原因。

3.前置++和后置++重载:

        同样我们用日期类来看看前置++和后置++:

class Date
{
public:Date(int year=2023,int month=9,int day=15){_year=year;_month=month;_day=day;}    Date(const Date& d){_year=d._year;_month=d._month;_day=d._day;}//前置++Date& operator++(){_day++;return *this;}//前置++//C++规定:后置++重载时多增加一个整形参数,但调用函数时该参数不用传递,编译器自动传递Date operator++(int){因为前置++返回的是没有改变前的值,所以要备份一个tmp且因为出了作用域后tmp会摧毁,所以返回值不能使用引用Date tmp(*this);_day++;return tmp;}
private:int _year;int _month;int _day;
};

4.const成员:

将const修饰的成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针。

5.取地址及const取地址操作符重载:

        这两个默认成员函数一般不用重新定义,编译器默认会生成,只有特殊情况才需要重载,比如想让别人读取到指定内容。

总结:

        文章到这,我们关于类的六个默认成员函数已经介绍完了,也是构造函数,析构函数,拷贝构造函数,赋值运算符重载,const成员函数,取地址及const取地址操作符重载。

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

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

相关文章

【Linux从入门到精通】多线程 | 线程互斥(互斥锁)

上篇文章我们对线程 | 线程介绍&线程控制介绍后&#xff0c;本篇文章将会对多线程中的线程互斥与互斥锁的概念进行详解。同时结合实际例子解释了可重入与不被重入函数、临界资源与临界区和原子性的概念。希望本篇文章会对你有所帮助。 文章目录 引入 一、重入与临界 1、1 可…

HTML显示中文空格字符,emsp;一个中文字符,ensp;半个中文字符

&emsp;一个中文字符 &ensp;半个中文字符 <ul><li class"li">姓&emsp;&emsp;名&#xff1a;<input type"text" /></li><li class"li">手&ensp;机&ensp;号&#xff1a;<input type"…

react ant ice3 实现点击一级菜单自动打开它下面最深的第一个子菜单

1.问题 默认的如果没有你的菜单结构是这样的&#xff1a; [{children: [{name: "通用配置"parentId: "1744857774620672"path: "basic"}],name: "系统管理"parentId: "-1"path: "system"} ]可以看到每层菜单的p…

和数集团:我国区块链行业发展具有广阔前景

区块链技术正在引领全球新一轮技术变革和产业变革&#xff0c;推动“信息互联网”向“价值互联网”变迁。 公开资料显示&#xff0c;区块链是一种由多方共同维护&#xff0c;使用密码学保证传输和访问安全&#xff0c;能够实现数据一致存储、难以篡改、防止抵赖的记账技术&…

视频监控/安防监控/AI视频分析/边缘计算EasyCVR平台如何调取登录接口获取token?

安防视频监控管理平台/视频汇聚/视频云存储平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;实现视频资源的鉴权管理、按需调阅、全网分发、云存储、AI智能分析等&#xff0c;视频监控智能分析平台EasyCVR融合性强、…

Gmail邮箱注册情况及最新动态

在中国大陆地区&#xff0c;对于是否可以注册Gmail邮箱一直存在一定的限制和讨论。准确来说&#xff0c;中国大陆地区的用户目前无法直接访问和注册Gmail邮箱。由于某些政策和技术原因&#xff0c;中国政府对于一些外国的网站和服务实施了网络封锁与限制。因此&#xff0c;中国…

地奥“畅依笙”革故鼎新,新品面市! 呵护肠胃 助力大健康!

根据平安健康发布的《2021国民肠道健康调研报告》&#xff0c;肠道问题逐渐年轻化&#xff0c;约90%的国人都会遇到肠道问题。我国肠胃终端产品持续热销&#xff0c;根据2021年淘宝天猫全年益生菌保健品/功能食品市场规模&#xff0c;销售额达63.2亿元&#xff1b;目前益生菌类…

密码学【一】

前言 在区块链的整个体系中大量使用了密码学算法&#xff0c;比如用于 PoW 的哈希算法&#xff0c;用于完整性验证的 Merkle Tree&#xff0c;用于交易签名与验证的数字签名算法&#xff0c;用于隐私保护的零知识证明等等。 可以说密码学是保证区块链安全的基石&#xff0c;而区…

JDK9特性——语法、API的改变

文章目录 语法层次改变钻石操作符号语法升级try结构语法升级下划线命名标识符的使用限制 API层次的改变接口中的私有方法String底层存储结构变化Stream新增4个APIInputStream新增transferTo方法只读集合创建 语法层次改变 钻石操作符号语法升级 钻石操作符&#xff0c;就是我…

css relative 和absolute布局

1、relative和absolute内部的元素都是相对于父容器&#xff0c;若父容器没有指定为relative&#xff0c;则默认为整个文档视图空间&#xff0c;absolute可以重叠元素&#xff0c;relative则不行。relative意味着元素的任意属性如left和right都是相对于其他元素的。absolute则相…

正确理解芯片解密,解除偏见

正确理解芯片解密&#xff0c;解除偏见 电子半导体技术在当今时代如日中天&#xff0c;许多行业都有着它的应用&#xff0c;芯片解密也不例外。那么什么是芯片解密&#xff1f;芯片解密是一种新兴的逆向工程技术&#xff0c;它利用半导体逆向技术来解密加密后的芯片&#xff0c…

华为开源自研AI框架昇思MindSpore应用案例:消噪的Diffusion扩散模型

目录 一、环境准备1.进入ModelArts官网2.使用CodeLab体验Notebook实例 二、案例实现构建Diffusion模型位置向量ResNet/ConvNeXT块Attention模块组归一化条件U-Net正向扩散数据准备与处理采样训练过程推理过程&#xff08;从模型中采样&#xff09; 本文基于Hugging Face&#x…

数据结构入门 — 树的概念与结构

本文属于数据结构专栏文章&#xff0c;适合数据结构入门者学习&#xff0c;涵盖数据结构基础的知识和内容体系&#xff0c;文章在介绍数据结构时会配合上动图演示&#xff0c;方便初学者在学习数据结构时理解和学习&#xff0c;了解数据结构系列专栏点击下方链接。 博客主页&am…

华为云云耀云服务器L实例评测|基于Docker环境快速部署Halo个人博客实操

目录 一、基本介绍 1.1 云耀云服务器L实例介绍 1.2 实操介绍 二、云耀云服务器的购买及基本使用 2.1 服务器购买流程 2.2 初始化连接流程 2.3 系统环境检查 三、Docker中运行Halo 3.1 Halo基本介绍 3.2 Docker的安装 3.3 使用 Docker 镜像创建容器 四、安装初始化H…

《Linux从练气到飞升》No.22 Linux 基础IO

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…

prize_p1

文章目录 解题过程代码审计思路问题解决数组绕过preg_match__destruct的触发修改phar文件以及签名phar://支持的后缀(其他方法) 题解方法一&#xff08;数组绕过&#xff09;方法二&#xff08;gzip绕过&#xff09; 解题过程 源代码 <META http-equiv"Content-Type&q…

谷歌翻译API接口,翻译API接口,翻译API接口申请指南

Google翻译API是一种可以在多个平台上使用的Web服务&#xff0c;通过使用该API&#xff0c;用户可以将任何文本转换成多种语言&#xff0c;同时也可以将多种语言转换成用户指定的语言。目前Google翻译API支持超过100种语言&#xff0c;涵盖了全球范围内的所有主流语言。 Googl…

Linux C 多线程

为什么会有线程? ————————>>>> 进程实现多任务的缺点&#xff1a; 进程间切换的计算机资源开销很大&#xff0c;切换效率非常低进程间数据共享的开销也很大 线程和进程的关系 线程是进程的一个执行单元&#xff0c;是进程内的调度实体。比进程…

在PHP8中对数组进行排序-PHP8知识详解

在php8中&#xff0c;提供了丰富的排序函数&#xff0c;可以对数组进行排序操作。常见的排序函数如下几个&#xff1a;sort() 函数、rsort() 函数、asort() 函数、arsort() 函数、ksort() 函数、krsort() 函数、natsort()函数和natcascsort()函数。 1、sort() 函数&#xff1a;…

从0到1学会Git(第三部分):Git的远程仓库链接与操作

写在前面:前面两篇文章我们已经学会了git如何在本地进行使用&#xff0c;这篇文章将讲解如何将本地的git仓库和云端的远程仓库链接起来并使用 为什么要使用远程仓库:因为我们需要拷贝我们的代码给别人以及进行协同开发&#xff0c;就需要有一个云端仓库进行代码的存储和同步&a…