【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.hqwc.cn/news/109851.html

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

相关文章

Java集合(Collection、Iterator、Map、Collections)概述——Java第十三讲

前言 本讲我们将继续来讲解Java的其他重要知识点——Java集合。Java集合框架是Java编程语言中一个重要的部分,它提供了一套预定义的类和接口,供程序员使用数据结构来存储和操作一组对象。Java集合框架主要包括两种类型:一种是集合(Collection),存储一个元素列表,…

运维Shell牛刀小试(十一):for循环读取多个命令行参数

运维Shell脚本小试牛刀(一) 运维Shell脚本小试牛刀(二) 运维Shell脚本小试牛刀(三)::$(cd $(dirname $0)&#xff1b; pwd)命令详解 运维Shell脚本小试牛刀(四): 多层嵌套if...elif...elif....else fi_蜗牛杨哥的博客-CSDN博客 Cenos7安装小火车程序动画 运维Shell脚本小试…

【SpringCloud微服务项目实战-mall4cloud项目(2)】——mall4cloud-gateway

mall4cloud-gateway网关模块 系统架构与网关介绍网关介绍 网关层代码依赖引入bootstrap配置nacos配置gateway配置处理跨域问题gateway路由断言配置gateway路由过滤配置 总结 代码地址 github地址 fork自github原始项目 gitee地址 fork自gitee原始项目 系统架构与网关介绍 从图…

深圳唯创知音电子将参加IOTE 2023第二十届国际物联网展•深圳站

​ 2023年9月20~22日&#xff0c;深圳唯创知音电子将在 深圳宝安国际会展中心&#xff08;9号馆9B1&#xff09;为您全面展示最新的芯片产品及应用方案&#xff0c;助力传感器行业的发展。 作为全球领先的芯片供应商之一&#xff0c;深圳唯创知音电子一直致力于为提供高质量、…

JVM 篇

一、知识点汇总 其中内存模型&#xff0c;类加载机制&#xff0c;GC是重点方面。性能调优部分更偏向应用&#xff0c;重点突出实践能力。编译器优化和执行模式部分偏向于理论基础&#xff0c;重点掌握知识点。 内存模型&#xff1a;各部分作用&#xff0c;保存哪些数据。类加载…

java设计模式之观察者模式

. 基本概念 观察者&#xff08;Observer&#xff09;模式中包含两种对象&#xff0c;分别是目标对象和观察者对象。在目标对象和观察者对象间存在着一种一对多的对应关系&#xff0c;当这个目标对象的状态发生变化时&#xff0c;所有依赖于它的观察者对象都会得到通知并执行它…

数据分享|R语言分析上海空气质量指数数据:kmean聚类、层次聚类、时间序列分析:arima模型、指数平滑法...

全文链接&#xff1a;http://tecdat.cn/?p30131 最近我们被客户要求撰写关于上海空气质量指数的研究报告。本文向大家介绍R语言对上海PM2.5等空气质量数据&#xff08;查看文末了解数据免费获取方式&#xff09;间的相关分析和预测分析&#xff0c;主要内容包括其使用实例&…

嵌入式-数据进制之间的转换

目录 一.简介 1.1十进制 1.2二进制 1.3八进制 1.4十六进制 二.进制转换 2.1二进制-十进制转换 2.2八进制-十进制转换 2.3十六进制-十进制转换 2.4十进制-二进制转换 2.5十进制-八进制转换 2.6十进制-十六进制转换 2.7小数部分转换 一.简介 被传入到计算机的数据要…

SpringBoot-接口幂等性

幂等 幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。 幂等函数或幂等方法是指可以使用相同参数重复执行&#xff0c;并能获得相同结果的函数。这些函数不会影响系统状态&#xff0c;也不用担心重复执行会对系统造成改变。 尤其是支付、订单等与金钱挂…

华硕电脑怎么录屏?分享实用录制经验!

“华硕电脑怎么录屏呀&#xff0c;刚买的笔记本电脑&#xff0c;是华硕的&#xff0c;自我感觉挺好用的&#xff0c;但是不知道怎么录屏&#xff0c;最近刚好要录一个教程&#xff0c;怎么都找不到在哪里录制&#xff0c;有人能教教我吗&#xff1f;” 随着电脑技术的不断发展…

包管理工具--》其他包管理器之cnpm、pnpm、nvm

包管理工具系列文章目录 一、包管理工具--》npm的配置及使用&#xff08;一&#xff09; 二、包管理工具--》npm的配置及使用&#xff08;二&#xff09; 三、包管理工具--》发布一个自己的npm包 四、包管理工具--》yarn的配置及使用 五、包管理工具--》其他包管理器之cnpm…

javascript检测网页缩放演示代码

一、为什么会提示浏览器显示比例不正常&#xff1f; 在网上冲浪&#xff0c;有时在打某个网站时&#xff0c;会提示你的浏览器显示比例不是100%&#xff0c;建议你将浏览器显示比例恢复为100%&#xff0c;以便获得最佳显示效果。 二、检测网页缩放比例的方法 那么这些网站是如…