- 📢博客主页:https://loewen.blog.csdn.net
- 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
- 📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉
- 📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨
文章预览:
-
-
- [一. 重载运算符](#一. 重载运算符)
- [二. 赋值运算符重载](#二. 赋值运算符重载)
- [三. 析构函数](#三. 析构函数)
-
一. 重载运算符
1、运算符:
- 算术运算符:
+、-、*、/、%
; - 赋值运算符:
=
; - 关系运算符:
>、<、>=、<=、==、!=
; - 逻辑运算符:
&&,||
;等
2、重载运算符 :就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
🐾 特性 :运算符重载本质上就是一个函数:
- 在函数体内实现想要的功能,当用到该运算符时,编译器会自动调用这个函数;
- 有返回类型和参数列表;
也就是说,运算符重载是通过函数实现的,它本质上是函数重载。
💐 语法 :函数的名字由关键字operator
及其紧跟的运算符组成 ,比如:重载+运算符 ==>operator+ 重载=号运算 ==>operator=
🌸 其他:
有一些运算符的重载系统会自动生成,比如赋值运算符=
,而有些运算符的重载系统不会自动生成,需要我们手动定义,比如关系运算符==
。
比如定义类的两个对象:
cpp
class Time
{
public:
Time();
int Hour;
int Minute;
int Second;
};
cpp
int main()
{
Time myTime;
Time myTime2;
if(myTime == myTime2); //比较对象A和对象B,不可以,比较运算符"=="缺省的情况下,系统不会自动生成,
//并且系统不知道你要在什么样的条件下,才能判断两个对象是否相等,
//所以需要自己对比较运算符"=="来重新定义,用于两个对象的比较。
myTime = myTime2; //将对象B赋值给对象A,可以,赋值运算符"="缺省的情况下, 系统会自动生成。
return 0;
}
那么如何重新定义比较运算符==
,使其可以判断两个对象是否相等呢?
这里的重新定义即比较运算符重载,我们可以规定某些规则来判断两个对象是否相等,比如当它的两个成员变量Hour之间的值相等时,我们可以判断两个对象相等之类的。
二. 赋值运算符重载
前面我们有提到过,如果赋值运算符"="缺省的情况下,系统会自动生成一个默认的赋值运算符重载(函数)实现对象的赋值,将对象myTime2
的数据成员逐一拷贝到对象myTime
中。
虽然默认的赋值运算符重载(函数)能够实现很多拷贝,但是有很多时候它是不行的,这时需要对赋值运算符进行重载(重新定义)。
✨ 格式: T & operator=(const T&)
- 参数类型:const T&,传递引用可以提高传参效率;
const
修饰:防止赋值的时候,参数值被修改; - 返回
*this
:返回自身对象的引用,即等号=左边对象(下文myTime6
)的地址;
cpp
class Time
{
public:
Time();
int Hour;
int Minute;
int Second;
Time(const Time &tmptime,int a = 5);
Time & operator=(const Time&); //若禁止赋值运算符重载的时候,将其声明为private即可
};
cpp
Time::Time():Hour(11), Minute(58), Second(49)
{
std::cout << "调用了Time::Time()构造区数" << std::endl;
}
Time::Time(const Time &tmptime, int a)
{
std::cout << "调用了Time::Time(Time &taptime, int a)拷贝构造区数" << std::endl;
}
//赋值运算符重载
Time & Time::operator=(const Time& tmp)
{
Hour = tmp.Hour;
Minute = tmp.Minute;
Second = tmp.Second;
std::cout << "调用了Time & Time::operator=(const Time& tmp)赋值运算符重载" << std::endl;
return *this; //返回自身对象的引用
}
cpp
int main()
{
Time myTime; //调用构造函数
Time myTime5 = { myTime }; //调用拷贝构造函数
Time myTime6; //调用默认构造函数(不带参数)
myTime6 = myTime5; //这个是赋值运算符,即没调用构造函数,也没调用拷贝构造函数
//但系统会调用一个赋值运算符重载
return 0;
}
可以看到,在最后执行myTime6 = myTime5
时,调用了我们自己定义的赋值运算符重载,目的是可以更精确的控制类Time
的赋值操作。
其中,在执行myTime6 = myTime5
时,会调用Time & Time::operator=(const Time& tmp)
赋值运算符函数。即:将myTime5
的地址赋值给参数tmp
,在函数内部完成一系列赋值操作后,再将对象的引用返回给myTime6
。从而完成myTime5
对myTime6
的赋值操作。
三. 析构函数
🐶 定义: 「析构函数 」是特殊的类成员函数,「析构函数 」 与 「构造函数 」的作用正好相反,「构造函数 」是对象创建的时候自动调用的,而 「析构函数」就是对象在销毁的时候自动调用的的。
🐵 格式: ~类名()
🐭 特性:
- 默认生成性 :同于「构造函数 」,如果不显式的定义「析构函数 」,编译器会生成一个默认的函数体为空的「析构函数」;
- 唯一性 :不同于「构造函数 」可以有多个重载函数(名同、参不同),「析构函数」只有一个,并且因为不接收任何参数,所以不能被重载;
cpp
class Time
{
public:
Time();
~Time();
};
cpp
Time::~Time()
{
std::cout << "调用了Time::~Time()析构函数" << std::endl;
}
cpp
int main()
{
Time myTime;
Time myTime1 = { myTime };
system("pause");
return 0;
}
因为在main
函数体内创建了两个局部类对象,所以在main
函数结束时(return
之前)会自动调用两次析构函数(若为全局对象,则会在程序运行结束时调用析构函数)。
🐷 new对象和delete对象(配对使用):
cpp
Time *ptime = new Time(); //new动态创建类对象,这时系统会调用类Time的构造函数
delete ptime; //delete手动释放内存,这时系统会调用类Time的析构函数
有的人可能会觉得,若Time *ptime = new Time()
出现在某个函数中时,认为其是个局部指针,会在函数运行结束之后ptime
的内存被自动释放掉。这种想法是错误的,记住只要出现new
,一定要delete
手动释放其创建的内存。
总结: 对于用new
动态创建的对象,一定要在程序停止运行的某个时刻,手动delete
释放掉其内存,否则就会造成内存泄漏。
|------------------------------------------------------------|
| 态度"ABC"理论的三个维度,即情感(Affective)、行为(Behavioral)和认知(Cognitive) |