运算符重载是C++中的一个重要特性,它允许程序员为自定义类型(类)定义运算符的行为。以下是运算符重载在C++语言中的一些应用:
1. **自定义数据类型的运算**:通过运算符重载,可以使自定义类的对象像内置类型一样进行运算。例如,可以重载加法运算符(`+`)来实现两个对象的相加。
2. **增强可读性**:运算符重载使得代码更加直观和易读。例如,使用`a + b`来表示两个复数的相加,而不是调用一个函数`add(a, b)`。
3. **实现链式调用**:通过返回对象的引用,可以实现链式调用,使得多个运算可以在一行中完成。
4. **支持标准库算法**:运算符重载使得自定义类型可以与标准库中的算法(如排序、查找等)兼容,增强了代码的灵活性。
5. **实现比较操作**:可以重载比较运算符(如`==`、`!=`、`<`、`>`等),使得自定义类型的对象可以直接进行比较。
6. **输入输出流**:通过重载`<<`和`>>`运算符,可以方便地实现自定义类型的输入输出,增强与用户的交互。
7. **内存管理**:在某些情况下,可以重载运算符来实现资源管理,例如重载`new`和`delete`运算符来控制内存分配和释放。
运算符重载使得C++在处理复杂数据类型时更加灵活和高效,是面向对象编程的重要组成部分。
一.加号运算符重载
在c++中,我们为了实现自定义数据进行相加,我们通常使用加号运算重载,从而以提高我们代码运行效率。比如在类中,实现两个对象的相加,是无法直接写成一个对像加上另一个类的,编译器是识别不出你将要对哪两个成员变量相加,从而出现错误。
比如一下操作:
/*如果你想进行两个对象的相加比如
* 定义三个对象 person p1,person p2,person p3
* p3=p1+p2;
在你的想法中可能进行得操作是:p3.m_a=p1.m_a+p2.m_a;p3.m_b=p1.m_b+p2.m_b;
可是并不是这样的,如果想达到这样的效果你可以尝试用加号运算符重载;
*/
#include<iostream>
using namespace std;
class person {
public:
int m_a;
int m_b;
person()
{};
person(int a, int b)
{
m_a = a;
m_b = b;
}
person personaddperson(person& p)//定义一个加号运算符重载成员函数,
{
person temp;
temp.m_a = this->m_a + p.m_a;
temp.m_b = this->m_b + p.m_b;
return temp;
}
};
void test01()
{
person p1(10,20);
person p2(10,20);
person p3;
p3 = p1.personaddperson(p2);
cout << "p1.m_a" << p1.m_a << "p1.m_b " << p1.m_b << endl;
cout << "p2.m_a" << p2.m_a << "p2.m_b " << p2.m_b << endl;
cout << "p3.m_a" << p3.m_a << "p3.m_b " << p3.m_b << endl;
}
int main()
{
test01();
}
在该代码中虽然已经实现了两个对象的直接相加,但是并没有达到p3=p1+p2这样的效果,如果想达到这样的效果我们需要将加号运算符重载的名字改为 operator+ ,这样将会达到这样的效果;
例如以下代码:
/*如果你想进行两个对象的相加比如
* 定义三个对象 person p1,person p2,person p3
* p3=p1+p2;
在你的想法中可能进行得操作是:p3.m_a=p1.m_a+p2.m_a;p3.m_b=p1.m_b+p2.m_b;
可是并不是这样的,如果想达到这样的效果你可以尝试用加号运算符重载;
*/
#include<iostream>
using namespace std;
class person {
public:
int m_a;
int m_b;
person()
{};
person(int a, int b)
{
m_a = a;
m_b = b;
}
/*person personaddperson(person& p)//定义一个加号运算符重载成员函数,
{
person temp;
temp.m_a = this->m_a + p.m_a;
temp.m_b = this->m_b + p.m_b;
return temp;
}*/
/*person operator+(person& p)//定义一个加号运算符重载成员函数,
{
person temp;
temp.m_a = this->m_a + p.m_a;
temp.m_b = this->m_b + p.m_b;
return temp;
}*/
};
person& operator+(person &p1,person &p2)//定义一个加号运算符重载全局函数,
{
person temp;
temp.m_a = p1.m_a + p2.m_a;
temp.m_b = p1.m_b + p2.m_b;
return temp;
}
void test01()
{
person p1(10,20);
person p2(10,20);
person p3=p1+p2;
//p3 = p1.personaddperson(p2);
cout << "p1.m_a" << p1.m_a << "p1.m_b " << p1.m_b << endl;
cout << "p2.m_a" << p2.m_a << "p2.m_b " << p2.m_b << endl;
cout << "p3.m_a" << p3.m_a << "p3.m_b " << p3.m_b << endl;
}
int main()
{
test01();
}
在该代码中,不仅达到了预期效果,也将加号运算符重载函数变成了全局函数,但是代码里面也注释了成员函数如何表示。
二.左移运算符重载
左移运算符在c++中我们会用在对自定义类型的输出等应用中,比如输出一个对象 p,cout<<p;计算机并不知道如何该对象,它也并不会将该对象所包含的全部成员变量逐个输出,所以在这种场合我们会用上左移运算符重载的知识。
比如以下代码:
#include <iostream>
using namespace std;
class person {
//当在成员函数中定义左移运算符重载函数时
//因为我们要输出一个对象,并且要简化为cout<<p;
//函数的形参要为ostream类型此类型为cout的数据类型。
//person operator<<(ostream cout)//调用该函数是不是为p.operator<<(cout)简化为p<<cout;并不能达到预期效果;
public:
int m_a;
int m_b;
person(int a, int b)
{
this->m_a = a;
this->m_b = b;
}
};
void operator<<( ostream &cout,person &p)//cout在左边p在右边才能简化为cout<<p;
{
cout << p.m_a << p.m_b;
}
int main()
{
person p1(10, 20);
cout << p1;
}
你会发现左移运算符重载只能定义为全局函数,但是在代码中你还会发现用cout输出的时候后面不能加<<endl;关于这个问题你看一下函数的类型是void,所以如果cout<<p<<endl;相当于void<<endl;自然不对,所以我们应该让函数返回cout类型,因此代码应该改成
#include <iostream>
using namespace std;
class person {
//当在成员函数中定义左移运算符重载函数时
//因为我们要输出一个对象,并且要简化为cout<<p;
//函数的形参要为ostream类型此类型为cout的数据类型。
//person operator<<(ostream cout)//调用该函数是不是为p.operator<<(cout)简化为p<<cout;并不能达到预期效果;
public:
int m_a;
int m_b;
person(int a, int b)
{
this->m_a = a;
this->m_b = b;
}
};
ostream& operator<<( ostream &cout,person &p)//cout在左边p在右边才能简化为cout<<p;
{
cout << p.m_a << p.m_b;
return cout;
}
int main()
{
person p1(10, 20);
cout << p1<<endl;
}
三. 递增运算符重载
对与递增运算符重载主要还是应用与对自定义数据类型进行递增,从而简化代码。提高效率;
比如对于一个对象进行递增,计算机时无法理解的,当我们想让一个对象的递增就是让该对象所包含的整数成员函数进行递增;
比如以下代码:
#include<iostream>
using namespace std;
class person{
public:
person(int a, int b)
{
a_ = a;
b_ = b;
}
/*person& operator++()//递增运算符重载,前置递增
{
a_++;
b_++;
return *this;
}*/
person operator++(int)//此出int做占位参数为了与前置递增区分,并且后置递增返回的是本身不是引用因为函数结束后temp会被释放
{
//后置递增首先是要记录
person temp = *this;
//然后进行递增
a_++;
b_++;
//最后进行记录结果
return temp;
}
int a_;
int b_;
};
ostream& operator<<(ostream& cout, const person& p)
{
cout << p.a_ <<" " << p.b_;
return cout;
}
int main()
{
person test(0,0);
cout << test++ << endl;
cout << test<<endl;
}
代码里包含了两种递增的代码补充,一定要注意区别哦;
四.关系运算符重载
对与关系运算符重载作用大致与上面的相同,所以咱们废话少说直接看代码
#include<iostream>
using namespace std;
class person {
public:
person(int a, int b)
{
a_ = a;
b_ = b;
}
//对与关系运算符重载我们用再来直接比较两个对象
//常见的关系运算符分为
//等于与不等于
//咱只写等于的情况,对与不等于和该代码大致相同
bool operator==(person p)
{
if (this->a_ == p.a_ && this->b_ == p.b_)
return true;
else return false;
}
int a_;
int b_;
};
ostream& operator<<(ostream& cout, const person& p)
{
cout << p.a_ << " " << p.b_;
return cout;
}
int main()
{
person p1(0, 0);
person p2(2, 2);
if (p1 == p2)
cout << "两个对象相等" << endl;
else
cout << "两个对象不相等"<<endl;
}
这就是本章节大致内容了,可能还有很多其他的运算符重载,作者可能还没有学会!!
ok,再见了,有什么问题可以提出来啊,作者将积极改正!
标签:p1,temp,int,运算符,person,重载 From: https://blog.csdn.net/2302_79462688/article/details/143097887