欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > 【C++】类与对象(中下)

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

2025/6/27 15:47:04 来源:https://blog.csdn.net/2301_80349538/article/details/145146180  浏览:    关键词:【C++】类与对象(中下)

 目录

💕1.运算符重载何时使用

💕2.运算符重载的定义 

💕3.分析两段代码 

目录3:总结->:

 💕4.运算符重载前置与后置++(或者类似情况)的写法


(最新更新时间——2025.1.15)

风雪虽寒

也就这般

💕1.运算符重载何时使用

如果不做特殊处理,C++ 的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算。

什么意思?请看图片->:

当我们创建两个类的对象时,我们想让这两个对象进行操作符运算(如:+,-,*,/,==等)都是不可以直接运算的,这时候就要运用到运算符重载

💕2.运算符重载的定义 

1.运算符重载是具有特殊名字的函数,他的名字是由operator和后面要定义的运算符共同构成。和其他函数⼀样,它也具有其返回类型和参数列表以及函数体

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

3.用于operator的运算符,其含义不能变,例如:operator函数里面实现的是+的功能,你不能命名成operator-(但其实你更改也没有关系,编译器识别不出来)

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

5.以上5个运算符不能用于重载,这个经常在笔试题中出现


什么意思?请看代码->:

#include<iostream>
#include<stdlib.h>
using namespace std;
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}
public:int _year;int _month;int _day;
};
//可以换返回类型与形参
bool operator==(Date& s1, Date& s2)
{if (s1._year == s2._year){if (s1._month == s2._month){if (s1._day == s2._day){return true;}}}else{return false;}
}
int main()
{Date s1(2025, 1, 15);Date s2(2024, 1, 1);operator==(s1, s2);//等价operator==(s1, s2);s1 == s2;
}

如代码所示:我们利用关键字operator加上操作符,就可以让两个类类型的对象之间使用操作符,我们也可以自己更改操作符,operator关键字后面的操作符是给你自己识别的,你可以随意更换

在我们使用operator关键字后,我们使用s1 == s2,实际上调用的就是    operator==(s1, s2);

注意!!!!!我在代码中类的成员变量都是public,这是因为如果是private,那么在类外的operator中就无法访问到year,month,day


接下来我们讲一下第四点

先看代码->:

#include<iostream>
#include<stdlib.h>
using namespace std;
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}bool operator==(Date& s1,Date& s2){if (_year == s2._year){if (_month == s2._month){if (_day == s2._day){return true;}}}else{return false;}}
private:int _year;int _month;int _day;
};int main()
{Date s1(2025, 1, 15);Date s2(2024, 1, 1);operator==(s1,s2);//s1==s2等价于operator==(s1,s2)s1 == s2;
}

如果我们这么写,编译器是会报错的,这是因为运算符重载作为类成员函数重载时,运算符重载的形参个数应该与实际需要操作的对象个数相同,而当我们放在类中时,我们讲到过类中的成员函数是有一个隐藏的this指针的,所以operator函数实际上有三个形参,这就导致多出一个形参,这是不可以的,对此,我们的操作应该是,"巧妙地应用this指针"

请看接下来的代码->:

#include<iostream>
#include<stdlib.h>
using namespace std;
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}bool operator==(Date& s2){return _year == s2._year&& _month == s2._month&& _day == s2._day;}
public:int _year;int _month;int _day;
};int main()
{Date s1(2025, 1, 15);Date s2(2025, 1, 15);s1.operator==(s2);//s1==s2等价于s1.operator==(s2)if (s1 == s2){cout << "true" << endl;}else{cout << "false" << endl;}
}

我们在类中的运算符重载,可以减去一个形参,在main函数中使用s1.operator,这样就会把s1的地址传给this指针,这样就不会导致形参个数为3超出实际操作形参为2的因果

💕3.分析两段代码 

Date func()
{Date d(2025, 1, 15);return d;
}
int main()
{	Date& ref = func();
}

第一段代码如上,分析一下不好的地方以及错在哪里?


首先->:指出最简单的错误,return返回的值是一个临时变量,临时变量具有常性,也就是说明临时变量不可以修改,所以在main函数中用ref接受时,应该用const修饰

接下来不好点写在更改后的代码中->:

Date func()
{//调用d的构造函数Date d(2025, 1, 15);//返回d时会执行Date tep = d,再将tep返回回去,这里的Date tep = d,会调用拷贝构造函数,影响内存与运行时间return d;
}
int main()
{	//用const修饰,不然会权限的放大const Date& ref = func();//注意://如果写成以下->:const Date ref = func();//这么写又会调用一次拷贝构造函数了,所以应该用引用
}

再看一段代码吧

Date& func()
{Date d(2025, 1, 15);return d;
}int main()
{	const Date& ref = func();
}

这段代码有没有问题呢?

其实也是有的,虽然看似没问题,但其实这里有一个野引用

详解写在以下代码中了

Date& func()
{	Date d(2025, 1, 15);//(最后看)如果写成static Date d(2025,1,15);可以避免//返回时执行的是Date& tep = d,这里属于引用,没有调用拷贝构造函数,也就是不会开辟新的空间//再将tep返回去return d;
}int main()
{		//这里的ref接受了tep,也就说明ref就是d的别名//但需要注意的是,d是一个类的对象,d的生命周期结束时会自动调用类的析构函数,也就会释放d的内存空间,这就导致ref指向的是一块未知的空间,就会形成野引用//这就导致当ref指向的空间被别的栈区使用时,就会更改ref的值,这是非常危险的const Date& ref = func();
}

目录3:总结->:

出了作用域,返回对象还在没有析构,那就可以用引用返回,减少拷贝
a、返回对象生命周期到了,会析构,传值返回
b、返回对象生命周期没到,不会析构,传引用返回

 💕4.运算符重载前置与后置++(或者类似情况)的写法

在使用运算符重载时,为了区分是前置++还是后置++,祖师爷规定:

为了区分,构成重载,给后置++,强行增加了一个int形参

这里不需要写形参名,因为接收值是多少不重要,也不需要用
这个参数仅仅是为了跟前置++构成重载区分


请看代码->:

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
using namespace std;
class Date
{
public:Date(int year = 1970, int month = 1, int day = 1){_year = year;_month = month;_day = day;}int _year;int _month;int _day;
};//前置++
Date& operator++(Date& s1, int)
{cout << "前置++" << endl;return s1;
}//后置++
Date& operator++(Date& s1)
{cout << "后置++" << endl;return s1;
}
int main()
{Date d1(2025, 1, 15);operator++(d1);operator++(d1, 5);cout << d1._day;
}

各位可以自己运行一下,我将运行截图放在下面:

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词