C++运算符重载
C++ 运算符重载
C++中预定义的运算符的操作对象只能是基本数据类型。
但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作。
因此可以重定义或重载大部分 C++ 内置的运算符。这样,您就能使用自定义类型的运算符。
运算符重载是通过创建运算符函数实现的,运算符函数定义了重载的运算符将要进行的操作。运算符函数的定义与其他函数的定义类似,唯一的区别是运算符函数的函数名是由关键字operator和其后要重载的运算符符号构成的。
重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
一. +运算符重载
重载+
运算符,我们可以给+
重新定义其含义。
例如:
// 使用内置的+运算符操作进行int类型的运算
int a = 10;
int b = 20;
int c = a + b; // 结果为30
如果我们使用+
运算符来运算我们的自定义数据类型时,需要重载+
运算符才可以。
举个例子:有个我们自定义的数据类型Person,有height和weight两个属性
class Person
{
public:
int height; // 身高
int weight; // 体重
Person(int height, int weight)
{
this->height = height;
this->weight = weight;
}
};
我们定义两个对象p1和p2;
Person p1(10,10); // 将p1的两个属性设置为10,10
Person p2(20,20); // 将p2的两个属性设置为20,20
如果我们想对p1和p2进行height和weight的分别相加的运算通过,我们需要:
int heigt = p1.height + p2.height;
int weight = p1.weight + p2.weight;
当然我们也可以通过重载+
运算符进行运算:
有两种方式:
- 成员函数重载
// 成员函数重载+
Person operator+(Person &p)
{
Person temp; // 创建一个Person对象temp,用来临时存储 两个对象相加的值
temp.height = this->height + p.height;
temp.weight = this->weight + p.weight;
return temp; // 返回 temp,为Person类型的对象
}
成员函数重载的本质:
cout << p1.operator+(p2).height << endl;
可以简写为:cout << (p1 + p2).height << endl;
- 全局函数重载1
// 全局函数重载+
Person operator+(Person& q, Person& p)
{
Person temp;
temp.height = q.height + p.height;
temp.weight = q.weight + p.weight;
return temp;
}
这种只能两个两个进行操作,在VS2019以后,重载的+运算符的结果是一个纯右值,不能作为左值进行计算,所以多个类的实例连续相加会报错。只能两两相加。
- 全局函数重载2
//在全局区开辟一段内存,不在全局函数中开辟,防止函数执行完成后系统回收
Person temp;
// 全局函数重载+
Person& operator+(Person& q, Person& p)
{
temp.height = q.height + p.height;
temp.weight = q.weight + p.weight;
return temp;
}
返回引用,同时注意不要在栈中开辟空间。
这种可以实现链式操作。
全局函数重载的本质:
cout << operator+(p1, p2).height << endl;
可以简写为:cout << (p1 + p2).height << endl;
// 输出验证一下
cout << (p1 + p2).height << endl;
cout << (p1 + p2).weight << endl;
如果有两个以上的对象进行操作:链式操作
Person p1(10, 10); // 将p1的两个属性设置为10,10
Person p2(20, 20); // 将p2的两个属性设置为20,20
Person p3(30, 30); // 将p3的两个属性设置为30,30
Person p4(40, 40); // 将p3的两个属性设置为40,40
Person p5(50, 50); // 将p3的两个属性设置为50,50
// 输出验证一下
cout << (p1 + p2 + p3 + p4 + p5).height << endl; //输出 150(10+20+30+40+50)
cout << (p1 + p2 + p3 + p4 + p5).weight << endl; //输出 150(10+20+30+40+50)
由此可见,适当的使用运算符重载可以使程序更加简洁,方便编程。
-
运算符的重载与+
类似,可以根据自己的需要进行编程。
二. 左移运算符>>重载
作用:可以输出自定义类型数据
还是以上一个代码为例子
重载<<
同样有两种方法:成员函数和全局函数。分别写一下:
- 成员函数重载:
要弄清成员函数重载的本质,即为对象调用成员函数,对象.函数名(参数);
比如我们想重载左移运算符用来格式化输出 对象的 height 和 weight
一开始可以这样写:
// 成员函数重载左移运算符
void operator<<(ostream& cout)
{
cout << "p的height= " << this->height << " p的weight= " << this->weight;
}
调用时:
p1.operator<<(cout); // 本质调用
p1 << cout; // 简化之后
这显然不符合我们的使用习惯。所以要用第二种方法:全局函数重载。
- 全局函数重载
// 将全局函数声明为友元函数,可以访问类中的私有成员
friend void operator<<(ostream& cout, Person& p);
// 全局函数重载左移运算符
void operator<<(ostream& cout, Person& p)
{
cout << "height= " << p.height << " weight= " << p.weight;
}
调用时:
operator<<(cout, p1); // 本质调用
cout << p1; // 简化之后
用这两种方法,我们成功的将左移运算符重载,使其有了我们想要的功能。
但发现,如果我们想进行链式操作,程序会报错。究其原因,是因为我们的返回类型为void
,进行链式操作时,两种类型不一致,所以无法进行操作。稍作修改,将返回类型改为cout
的返回类型就可以,也就是ostream
。
全局函数重载左移<<
运算符:
在类中将全局函数声明为友元函数
friend ostream& operator<<(ostream& cout, Person& p);
// 全局函数重载左移运算符
ostream& operator<<(ostream& cout, Person& p)
{
cout << "height= " << p.height << " weight= " << p.weight;
return cout;
}
这样一来,我们便可以实现链式操作了。
在运算符重载时,实现链式操作的关键就是注意返回类型,要根据实际情况来看,重载函数的返回值要跟后面进行操作的对象为同一类型,具体情况具体分析。
三. 关系运算符重载
同样是两种方法。以>
为例。
- 成员函数重载
// 成员函数重载
bool operator>(Person& p)
{
if (this->height > p.height)
return true;
else
return false;
}
调用时:
bool result1 = p2.operator>(p1); // 本质
bool result2 = p1 > p2; // 简化
cout << result1 << endl;
cout << result2 << endl;
- 全局函数重载
friend bool operator>(Person& p1, Person& p2); // 将全局函数声明为友元函数
// 全局函数重载
bool operator>(Person& p1, Person& p2)
{
if (p1.height > p2.height)
return true;
else
return false;
}
调用时:
bool result1 = p1 > p2; // 简化
bool result2 = operator>(p1,p2); // 本质
cout << result1 << endl;
cout << result2 << endl;
关于运算符的重载就先写到这里,最重要的是了解本质,就是用成员函数或者是全局函数重新定义一下该运算符的功能,然后去调用成员函数或者是全局函数。
目前就先写这么多吧,其他几种运算符的重载应该是大同小异,有机会的话会更加深入的学习一番。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)