https://www.bilibili.com/video/BV1et411b73Z?p=121&spm_id_from=pageDriverhttps://www.bilibili.com/video/BV1et411b73Z?p=121&spm_id_from=pageDriver
运算符重载概念:
对已有的运算符进行重新定义,赋予其另一种功能,以适应不同的数据类型
作用:实现两个自定义数据类型相加的相加
#include <iostream> using namespace std; //运算符重载:对已有的运算符重新进行定义,赋予其另一种功能,已适应不同的数据类型 //自己写成员函数,实现两个对象相加属性后返回新的对象 //加号运算符重载 class Person { public: 1、成员函数重载+号 //Person operator+(Person& p) //{ // Person tmp; // tmp.m_A = this->m_A + p.m_A; // tmp.m_B = this->m_B + p.m_B; // return tmp; //} int m_A; int m_B; }; Person operator+(Person& p1, Person& p2) { Person tmp; tmp.m_A = p1.m_A + p2.m_A; tmp.m_B = p1.m_B + p2.m_B; return tmp; } Person operator+(Person& p1, int num) { Person tmp; tmp.m_A = p1.m_A + num; tmp.m_B = p1.m_B + num; return tmp; } 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 = operator+(p1,p2); Person p3 = p1 + p2; //运算符重载 也可以发生函数重载 Person p4 = p1 + 100; cout << "p3.m_A = " << p3.m_A << endl; cout << "p3.m_B = " << p3.m_B << endl; cout << "p4.m_A = " << p4.m_A << endl; cout << "p4.m_B = " << p4.m_B << endl; } int main() { test01(); return 0; }
总结1:对于内置的数据类型的表达式的运算符是不可能改变的
总结2:不要滥用运算符重载
作用:可以输出自定义的数据类型
#include <iostream> using namespace std; //左移运算符重载 配合友元可以实现输出自定义数据类型 class Person { friend ostream& operator<<(ostream& cout, Person& p);//全局函数作为Person的好朋友,可以访问类中的私有内容 public: Person(int a,int b) { m_A = a; m_B = b; } private: //利用成员函数重载 左移运算符 //不会利用成员函数重载<< 运算符,因为无法实现cout 在左侧 /*void operator<<(cout) { }*/ int m_A; int m_B; }; //只能利用全局函数重载左移运算符 ostream& operator<<(ostream& cout, Person& p)//本质 operator << (cout,p) 简化 cout << p { cout << "m_A = " << p.m_A << " m_B = " << p.m_B << endl; return cout; } void test01() { Person p(10,10); /*p.m_A = 10; p.m_B = 10;*/ cout << p << endl; } int main() { test01(); return 0; }
作用:通过重载递增运算符,实现自己的整型数据
我们首先再来复习一下整型数据的递增运算符,分为前置和后置递增
++a 和a++
++a:先让a+1,返回值为a+1
a++:后让a+1,返回值为a
#include <iostream> using namespace std; //通过重载递增运算符,实现自己的整型数据 // 自定义整型 //前置递增返回引用 后置递增返回值 class MyInteger { friend ostream& operator<<(ostream& cout, MyInteger myint); public: MyInteger() { m_Num = 0; } //重载前置++运算符 MyInteger& operator++() { m_Num++; return *this; } //重载后置++运算符 //int代表的是占位参数,可以区分前置和后置递增 MyInteger operator++(int) { //先 记录当时结果 MyInteger tmp = *this; //后 递增 m_Num++; //最后将记录结果做返回 return tmp; } private: int m_Num; }; //重载<<运算符 ostream& operator<<(ostream& cout, MyInteger myint) { cout << myint.m_Num; return cout; } void test01() { MyInteger myint; cout << ++(++myint) << endl; cout << myint << endl; } void test02() { MyInteger myint; cout << myint++ << endl; cout << myint << endl; } int main() { //test01(); test02(); /*int a = 10; cout << ++a << endl; cout << a << endl; int b = 10; cout << b++ << endl; cout << b << endl;*/ return 0; }
C++编译器至少给一个类添加4个函数
1.默认构造函数(无参,函数体为空)
2.默认析构函数(无参,函数体为空)
3.默认拷贝构造函数,对属性进行值拷贝
4.赋值运算符 operator=,对属性进行值拷贝
如果类中有属性指向堆区,在赋值操作时也会有深浅拷贝问题
#include <iostream> using namespace std; //通过重载递增运算符,实现自己的整型数据 // 自定义整型 //前置递增返回引用 后置递增返回值 class MyInteger { friend ostream& operator<<(ostream& cout, MyInteger myint); public: MyInteger() { m_Num = 0; } //重载前置++运算符 MyInteger& operator++() { m_Num++; return *this; } //重载后置++运算符 //int代表的是占位参数,可以区分前置和后置递增 MyInteger operator++(int) { //先 记录当时结果 MyInteger tmp = *this; //后 递增 m_Num++; //最后将记录结果做返回 return tmp; } private: int m_Num; }; //重载<<运算符 ostream& operator<<(ostream& cout, MyInteger myint) { cout << myint.m_Num; return cout; } void test01() { MyInteger myint; cout << ++(++myint) << endl; cout << myint << endl; } void test02() { MyInteger myint; cout << myint++ << endl; cout << myint << endl; } int main() { //test01(); test02(); /*int a = 10; cout << ++a << endl; cout << a << endl; int b = 10; cout << b++ << endl; cout << b << endl;*/ 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; } bool operator!=(Person& p) { if (this->m_Name == p.m_Name || this->m_Age == p.m_Age) { return false; } return true; } string m_Name; int m_Age; }; void test01() { Person p1("Tom", 18); Person p2("Tom", 21); if (p1 == p2) { cout << "p1 == p2" << endl; } else { cout << "p1 != p2" << endl; } } int main() { test01(); return 0; }
函数调用运算符()也可以重载
由于重载后使用的方式非常像函数的调用方式,因此称为仿函数
仿函数没有固定写法非常灵活
#include <iostream> using namespace std; //函数调用运算符重载 //打印输出类 class MyPrint { public: //重载的函数调用运算符 void operator()(string test) { cout << test << endl; } }; void Myprint(string test) { cout << test << endl; } void test01() { MyPrint myprint; myprint("Hello World!");//由于使用起来非常类似于函数调用,因此称为仿函数 Myprint("Hello World!"); } //仿函数非常灵活,没有固定的写法 //加法类 class MyAdd { public: int operator()(int num1, int num2) { return num1 + num2; } }; void test02() { MyAdd myadd; int ret = myadd(100, 100); cout << "ret = " << ret << endl; //匿名函数对象 cout << MyAdd()(100, 100) << endl; } int main() { //test01(); test02(); return 0; }