运算符重载的概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。
作用:实现两个自定义数据类型相加的运算。
例如:两个整型相加编译器知道该怎么进行运算,如果是两个自定义出来的类型,两个Person想加,编译器就不知道该怎么运算了。
- #include
- #include
- using namespace std;
- //加号运算符重载
-
- class Person
- {
- public:
- //1.成员函数重载+
- /*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;
- }
- //函数函数重载版本
- Person operator+(Person& p1, int num)
- {
- Person temp;
- temp.m_A = p1.m_A + num;
- temp.m_B = p1.m_B + num;
- return temp;
- }
- void test01()
- {
- Person p1;
- p1.m_A = 10;
- p1.m_B = 10;
- Person p2;
- p2.m_A = 10;
- p2.m_B = 10;
- //成员函数重载本质调用
- //Person p3 = p1.operator+(p2);
- //Person p3 = p1 + p2;//可以简化成这种形式
-
- //全局函数重载的本质调用
- //Person p3 = operator+(p1,p2);
- //Person p3 = p1 + p2;//可以简化成这种形式
- /*cout << p3.m_A << endl;
- cout << p3.m_B << endl;*/
-
- //运算符重载也可以发生函数重载
- Person p3 = p1 + 10;
- cout << p3.m_A << endl;
- cout << p3.m_B << endl;
- }
- int main(void)
- {
- {
- test01();
- system("pause");
- return 0;
- }
-
总结:
作用:可以输出自定义的类型
- #include
- using namespace std;
- class Person
- {
- friend ostream& operator<<(ostream& cout, Person& p);
- public:
- Person(int a, int b)
- {
- m_A = a;
- m_B = b;
- }
- //利用成员函数重载左移运算符p.operator<<(cout)简化版本p<
- //一般我们不会利用成员函数来重载<<运算符,以为无法实现cout在左边
- /*void operator<<(ostream &cout,Person &p)
- {
- cout << p.m_A << endl;
- cout << p.m_B << endl;
- }*/
- private:
- int m_A;
- int m_B;
- };
- //只能利用全局函数来重载左移运算符
- ostream& operator<<(ostream &cout, Person &p) //这样写的本质就是operator<<(cout,p)简化版本就是cout<
- {
- cout << p.m_A << endl;
- cout << p.m_B << endl;
- return cout;//cout是ostream类型
- }
- void test()
- {
- Person p(10,10);
- cout << p << "hello world" << endl;
- }
- int main(void)
- {
- test();
- system("pause");
- return 0;
- }
-
作用:通过重载递增运算符,实现自己的整型数据。
- #include
- using namespace std;
- //重载递增运算符
- class MyInteger
- {
- friend ostream& operator<<(ostream& cout, MyInteger myint);
- public:
- MyInteger()
- {
- m_Num = 0;
- }
- //重载++运算符——前置
- //返回引用是为了一直对一个数据进行递增操作
- MyInteger& operator++()//返回引用
- {
- ++m_Num;
- return *this;//this是指向自身
- }
- //重载++运算符——后置
- //返回值不同不能作为函数重载的条件
- MyInteger operator++(int)//这个int在这里作为占位参数,用来区分前置递增和后置递增
- {
- //先 记录当时结果
- MyInteger temp = *this;
- //后 递增
- m_Num++;
- //最后 返回
- return temp;
- //后置递增要返回值,因为如果返回引用,这里相当于返回的是一个局部对象的引用。
- //局部对象在当前函数执行完毕之后就被释放掉了,还要返回引用就是非法操作。
- }
- private:
- int m_Num;
- };
- //全局函数重载左移运算符
- ostream& operator<<(ostream& cout, MyInteger myint)
- {
- cout << myint.m_Num << endl;
- return cout;
- }
- void test()
- {
- MyInteger myint;
- cout << ++(++myint);
- cout <
- }
- void test02()
- {
- MyInteger myint;
- cout << myint++ << endl;
- cout << myint << endl;
- }
- int main(void)
- {
- //test();
- test02();
- system("pause");
- return 0;
- }
-
总结:前置递增返回引用,后置递增返回值。
4.赋值运算符重载
C++编译器至少给一个类添加4个函数(前三个之前已经讲过了)
- 默认构造函数(无参,函数体为空)
- 默认析构函数(无参,函数体为空)
- 默认拷贝构造函数,对属性进行值拷贝
- 赋值运算符operator=,对属性进行值拷贝
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题。
- #include
- 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)
- {
- //编译器默认提供的是浅拷贝操作//m_Age = p.m_Age;
- //应该先判断是否有属性在堆区,如果有先释放干净,然后再深拷贝。
- if (m_Age != NULL)
- {
- delete m_Age;
- m_Age = NULL;
- }
- //深拷贝操作
- m_Age = new int(*p.m_Age);
- //指回自身的指针是this指针,返回对象本身
- return *this;
- }
- int *m_Age;
- };
- void test1()
- {
- Person p1(18);
- Person p2(20);
- Person p3(30);
- p3 = p2 = p1;
- cout << *(p1.m_Age) << endl;
- cout << *(p2.m_Age) << endl;
- cout << *(p3.m_Age) << endl;
- //三个人都是18
- }
- int main(void)
- {
- test1();
- system("pause");
- return 0;
- }
-
5.关系运算符重载
作用:重载关系运算符,可以让两个自定义类型对象进行对比操作
- #include
- #include
- using namespace std;
- class Person
- {
- public:
- //重载==
- bool operator==(Person &p)
- {
- if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
- {
- return true;
- }
- else
- return false;
- }
- bool operator!=(Person &p)
- {
- if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
- {
- return false;
- }
- else
- return true;
- }
- Person(string name, int age)
- {
- m_Name = name;
- m_Age = age;
- }
- string m_Name;
- int m_Age;
- };
- void test()
- {
- Person p1("张三", 20);
- Person p2("张三", 20);
- if (p1 == p2)
- {
- cout << "p1和p2是相等的" << endl;
- }
- else
- {
- cout << "p1和p2是不相等的" << endl;
- }
- if (p1 != p2)
- {
- cout << "p1和p2是不相等的" << endl;
- }
- else
- {
- cout << "p1和p2是相等的" << endl;
- }
- }
- int main(void)
- {
- test();
- system("pause");
- return 0;
- }
-
//内置数据类型可以比对,但是自定义类型不行如:person这个数据类型
6.函数调用运算符重载
- 函数调用运算符()也可以重载
- 由于重载后使用的方式非常像函数的调用,因此称为仿函数
- 仿函数没有固定写法,非常灵活
- #include
- #include
- using namespace std;
- //函数调用运算符重载
- class MyPrint
- {
- public:
- //重载函数调用运算符
- void operator()(string text)
- {
- cout << text << endl;
- }
-
- };
- //仿函数非常灵活,没有固定的写法
- //加法类
- class MyAdd
- {
- public:
- int operator()(int a, int b)
- {
- return a + b;
- }
- };
- void test()
- {
- MyPrint myprint;
- myprint("hello world");//这里myprint是上一行代码 MyPrint myprint;中的对象myprint
- //()是重载的东西 //重载后使用的方式非常像函数的调用,因此称为仿函数
- MyAdd myadd;
- cout << myadd(1, 2) << endl;
-
- //匿名函数对象 特点:当前行被执行完立即释放
- cout << MyAdd()(100,100) << endl;
- }
- void test02()
- {
- MyAdd myadd;
- int ret = myadd(100, 100);
- cout <<"ret="<
- }
- int main(void)
- {
- test();
- test02();
- system("pause");
- return 0;
- }
-
-
相关阅读:
Stream常用操作以及原理探索
Java Web 7 JavaScript 7.6 DOM
Python——弹幕词频统计及其文本分析(绘制词云)(含源代码)
计算机网络:数据链路层功能
Autofac 注入仓储模式
Android自定义控件(五) 自定义View实现Android Loading效果
Java中的线程等待和唤醒、线程死锁、常用的线程池类(多线程下篇含线程池的使用及原理)
【国外翻译】采访漫威视觉开发总监:AndyPark
SveletJs学习——简介模块
Linux的介绍和安装
-
原文地址:https://blog.csdn.net/LDBH66/article/details/133099498