拷贝构造函数与运算符重载(c++详解)

您所在的位置:网站首页 符能请吗 拷贝构造函数与运算符重载(c++详解)

拷贝构造函数与运算符重载(c++详解)

2024-07-18 04:21:15| 来源: 网络整理| 查看: 265

拷贝构造函数与运算符重载 拷贝构造函数引出拷贝构造函数 运算符重载引出运算符重载赋值运算符重载

拷贝构造函数引出

先给出日期类的定义:

class Date { public: Date(int year=1900,int month=1, int day=1) { _year = year; _month = month; _day = day; } void print() { cout public: stack(int capacity=4) { _a = (int*)malloc(sizeof(int)*capacity); _capacity = capacity; _size = 0; } ~stack { free(-a); _capacity=0; _size=0; } private: int* _a; int _size; int _capacity; }; int main() { stack s1; stack s2(s1); return 0; }

这里我们想干的是在建一个对象s2,这个对象也想s1一样有一样的一个一样大小的数组,但是我们发现 在这里插入图片描述 其他一样是一样了,但是s2的指针,和s1的指针竟然指向了同一块空间,这就是浅拷贝。比如说,我看见了舍友有一个很好用的手机,我想要一个跟他内存一样大的手机,而不是和他共用一个手机。

而且这个程序最后会崩溃,创建s2,s2后进系统上的栈,先出所以s2对象生命周期先结束,会调用我们写的析构函数(自己生成的析构函数不释放)释放对上的空间,而s1此时是浅拷贝,和他共用一个空间,生命周期结束,再次调用析构函数,又free了一次,完蛋。

由于日期类里面没有指针什么的,所以默认生成的就可以用,因为它只需要浅拷贝所有字节, 而栈里,则是必须我们要自己写一个拷贝构造实现深拷贝(要一块跟你一样大的空间,让指针指向自己的),因为不写,就出现了上述举例的情况 运算符重载引出

C++为了增加代码的可读性引入了运算符重载。自定义类型就可以像内置类型一样去用运算符。需要我们自己定义运算符重载

Date d; d+1;//日期加一天 运算符重载

运算符重载是具有特殊函数名的函数,也具有返回值类型,函数名字,及参数列表,其返回值类型与参数列表与普通函数类似。 函数名字:关键字operator后面接需要重载的运算符符号。 函数原型: 返回值类型 operator 后面接需要重载的运算符符号 注意:

不能通过连接其他符号创造新的操作符冲在操作符必须有一个类类型或者枚举类型的操作数用于内置类型的操作符其含义不能改变,例如内置的整形+,不能改变其含义作为类成员函数,其形参看起来比操作数数目少一,因为成员函数有个默认的形参this指向调用对象,限定为第一个形参。.* :: sizeof ?: . 以上五个运算符不能重载(面试选择题经常考)想用什么操作符去自己重载

第一次写了这样,忘记了作为成员函数的时候,第一个参数已经有了就是隐含的this指针,指向调用对象。 在这里插入图片描述 不需要改变所以加上const,传值的话外面会调用拷贝构造函数,传引用就不调用了。

bool operator==(const Date& d2) { return _year == d2._year && _month == d2._month && _day == d2._day; }

开始的时候运算符函数形参写的是这样 const Date d2,虽然也可以,但是传递过去会调用拷贝构造函数。 但是脑子一混,把operator==函数当成了拷贝构造函数,还在想拷贝构造函数的形参是const Date d2的话不就无穷调用了吗。(zzz,你不重新写拷贝构造函数,人家默认生成的的参数肯定是引用类型的,不用你操心)

赋值运算符重载

把d2的值赋值给d1,需要注意的是它与拷贝构造是不一样的。赋值说明的是,两个对象已经定义出来了。

Date d1; Date d2(2021,2,6); d1=d2;

而拷贝构造则是将d1的值直接初始化给d2。两者是不一样的

Date d1; Date d2(d1); //赋值重载 void operator=(const Date& d) { //自己赋值自己没有意义 //开始写成这样,让对象比较。。还要写一个运算符重载函数比较 if(*this!=d) if(this!=&d) { _year = d._year; _month = d._month; _day = d._day; } }

但是在我们的内置类型中是支持连续赋值的 比如说:

int i,j,k; i=j=k=10;

也就是说k=10,有一个返回值k,让j=k,返回j,又让i=j。 所以给我们的函数加上返回值,类型为类名,返回this所指向的对象

//赋值重载 Date operator=(const Date& d) { //自己赋值自己没有意义 if(this!=&d) { _year = d._year; _month = d._month; _day = d._day; } return *this; }

当返回值为Date类型,*this传递给外面需要两次拷贝构造(先传给临时变量(Date类型),临时变量再给外面用于接收的变量)

当返回值为Date&,临时变量是返回值的别名,减少一次拷贝构造。形参做引用(总共一次)也减少一次拷贝构造。 所以下面这样写一共减少了两次拷贝构造。

//最终版赋值重载 Date& operator=(const Date& d) { //自己赋值自己没有意义 if(this!=&d) { _year = d._year; _month = d._month; _day = d._day; } return *this; }

注意:返回值做引用有一个条件就是看你返回值的生命周期,假如this所指向的对象生命周期在本函数体内,那么this传给中间变量,此时this销毁,中间变量是个引用也跟着销毁。外面的变量接收不到它。但是在这里*this是d1对象,生命周期在main函数里,所以不用担心

当我们不写,他也会自动生成,不过默认生成的他也是只进行浅拷贝,只拷贝值,像之前写拷贝构造函数里的Static,里面的指针变量。当d1=d2时,两个对象里面的两个指针指向同一块空间,析构的时候释放两次,程序崩溃。



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


    图片新闻

    实验室药品柜的特性有哪些
    实验室药品柜是实验室家具的重要组成部分之一,主要
    小学科学实验中有哪些教学
    计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
    实验室各种仪器原理动图讲
    1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
    高中化学常见仪器及实验装
    1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
    微生物操作主要设备和器具
    今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
    浅谈通风柜使用基本常识
     众所周知,通风柜功能中最主要的就是排气功能。在

    专题文章

      CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭