对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
一、加号运算符重载
实现两个自定义数据类型相加的运算
通过成员函数重载+号、全局函数重载
#include<iostream>
using namespace std;
//加号运算符重载
//1、成员函数重载+号
class Person {
public:
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;
}
int m_A;
int m_B;
};
//2、全局函数重载
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 test() {
Person p1;
p1.m_A = 10;
p1.m_B = 10;
Person p2;
p2.m_A = 20;
p2.m_B = 20;
Person p3 = p1 + p2;
cout << "p3.m_A=" << p3.m_A << endl;
cout << "p3.m_B=" << p3.m_B << endl;
}
int main() {
test();
return 0;
}
二、左移运算符重载
直接输出对象而不单独输出对象属性就可以重载左移运算符,且只能用全局函数来重载左移运算符
#include<iostream>
using namespace std;
class Person {
friend ostream& operator<<(ostream& cout, Person& p);
public:
Person(int a, int b) {
m_A = a;
m_B = b;
}
private:
//不会利用成员函数重载<<运算符,因为无法实现cout在左侧
int m_A;
int m_B;
};
//只能利用全局函数来重载<<运算符
ostream & operator<<(ostream& cout, Person& p) {
cout << "m_A=" << p.m_A << "m_B=" << p.m_B;
return cout;
}
void test() {
Person p(10, 10);
cout << p << endl;
}
int main() {
test();
return 0;
}
三、递增运算符重载
#include<iostream>
using namespace std;
//重载递增运算符
//自定义整型
class MyInteger {
friend ostream& operator<<(ostream& cout, const MyInteger& m);
public:
MyInteger() {
m_Num = 0;
}
//重载前置++运算符,返回的是引用
//返回引用的作用是为了一直给一个数据进行递增
MyInteger &operator++() {
m_Num++;
return *this;//返回自身
}
//重载后置++运算符,返回的是值
//int代表占位参数,可以用来区分前置和后置递增
MyInteger operator++(int) {
//先记录当前结果
MyInteger temp = *this;
//后递增
m_Num++;
return temp;
}
private:
int m_Num;
};
//重载一下左移运算符
ostream &operator<<(ostream &cout,const MyInteger &m) {
cout << "m_Num=" << m.m_Num;
return cout;
}
void test01() {
MyInteger m;
cout << ++m << endl;
}
void test02() {
MyInteger m;
cout <<m++ << endl;
cout << m << endl;
}
int main() {
test01();
test02();
return 0;
}
四、赋值运算符重载
如果类中有属性指向堆区,做赋值操作时也会出现
#include<iostream>
using namespace std;
class Person {
public:
Person(int age) {
m_Age = new int(age);
}
~Person() {
if (m_Age != NULL) {
delete m_Age;
m_Age = NULL;
}
}
Person & operator=(Person& p) {
//先判断是否有属性在堆区,如果有的话先释放干净,然后进行深拷贝
if (m_Age != NULL) {
delete m_Age;
m_Age = NULL;
}
m_Age = new int(*p.m_Age);
return *this;
}
int* m_Age;
};
void test() {
Person p1(10);
Person p2(18);
Person p3(20);
p3=p2 = p1;
cout << "p1=" << *p1.m_Age << endl;
cout << "p2=" << *p2.m_Age << endl;
cout << "p3=" << *p3.m_Age << endl;
}
int main()
{
test();
return 0;
}
五、关系运算符重载
#include<iostream>
using namespace std;
class Person {
public:
Person(string name,int age) {
m_name = name;
m_age = age;
}
bool operator==(Person& p) {
if (this->m_name == p.m_name && this->m_age == p.m_age) {
return true;
}
return false;
}
string m_name;
int m_age;
};
void test() {
Person p1("Tom", 10);
Person p2("Jenny", 12);
if (p1 == p2) {
cout << "p1和p2是相等的" << endl;
}
else {
cout << "p1和p2是不相等的" << endl;
}
}
int main()
{
test();
return 0;
}
六、函数调用运算符重载
#include<iostream>
using namespace std;
class Myprint {
public:
void operator()(string test) {
cout << test << endl;
}
};
void Myprint02(string test) {
cout << test << endl;
}
void test() {
Myprint m;
m("hello world");//由于使用起来非常类似于函数调用,因此称为仿函数
Myprint02("helloworld");
}
//仿函数非常灵活,没有固定写法
class Myadd {
public:
int operator()(int num1, int num2) {
return num1 + num2;
}
};
void test02() {
Myadd m;
int ret = m(100, 100);
cout << "ret=" << ret << endl;
//匿名函数对象,当前执行完,可以立即释放对象
cout << Myadd()(100, 100) << endl;
}
int main()
{
test();
return 0;
}