5. 运算符重载
5.1 加号运算符重载
1 #include<iostream> 2 using namespace std; 3 4 // 加号运算符重载 5 6 class Person { 7 public: 8 //1. 成员函数重载“+” 9 Person operator+(Person& p) { 10 Person temp; 11 temp.m_A = this->m_A + p.m_A; 12 temp.m_B = this->m_B + p.m_B; 13 return temp; 14 } 15 16 int m_A; 17 int m_B; 18 }; 19 20 //2. 全局函数重载“+” 21 Person operator+(Person& p1, Person& p2) { 22 Person temp; 23 temp.m_A = p1.m_A + p2.m_A; 24 temp.m_B = p2.m_B + p2.m_B; 25 return temp; 26 } 27 28 void test01() { 29 Person p1; 30 p1.m_A = 10; 31 p1.m_B = 20; 32 33 Person p2; 34 p2.m_A = 10; 35 p2.m_B = 20; 36 37 Person p3 = p1 + p2; 38 39 cout << "p1 + p1:" << p3.m_A << " " << p3.m_B << endl; 40 41 } 42 43 int main() { 44 45 test01(); 46 47 system("pause"); 48 49 return 0; 50 } 51 52 53 // 总结 54 // 对已有的运算符进行重新定义。赋予其另一种功能,以适应不同的数据类型 55 // 运算符重载也可以发生函数重载
5.2 左移运算符重载
1 #include<iostream> 2 using namespace std; 3 4 5 class Person { 6 friend ostream& operator<<(ostream& cout, Person& p); 7 public: 8 Person(int a, int b) { 9 m_A = a; 10 m_B = b; 11 } 12 public: 13 14 //1. 利用成员函数重载“左移”运算符 15 // p.operator << (cout) 简化版本 p << cout 16 // 不会利用成员函数重载<<运算符,因为无法实现<<在左侧 17 // 故不能使用成员函数的方法!! 18 19 //int m_A; // public属性,可以类外访问 20 //int m_B; 21 22 private: 23 int m_A; //如果是私有属性,可以通过friend方法解决 24 int m_B; 25 }; 26 27 //2. 利用全局函数重载“左移<<”运算符 28 ostream& operator<<(ostream& cout, Person &p) { // 本质 operator << (cout, p) 简化 cout << p 29 // cout的数据类型是ostream,可以转到定义去查看 30 cout << "m_A = " << p.m_A << " m_B = " << p.m_B; 31 return cout; //链式编程思想,返回值类型为ostream 32 } 33 34 void test01() { 35 Person p(10, 20); 36 //p.m_A = 10; 37 //p.m_B = 10; 38 39 cout << p << endl;; 40 } 41 42 int main() { 43 44 test01(); 45 46 system("pause"); 47 48 return 0; 49 }
5.3 递增运算符重载
1 #include<iostream> 2 using namespace std; 3 4 // 递增(递减)运算符重载 5 6 class MyInteger { 7 friend ostream& operator<<(ostream& cout, MyInteger myint); 8 public: 9 MyInteger() { 10 m_Num = 0; 11 } 12 13 // 重载前置++运算符 14 // 返回引用是为了一直对一个数据进行递增操作 15 MyInteger& operator++() { 16 // 先进行++运算 17 m_Num++; 18 19 //再将自身返回 20 return *this; 21 } 22 23 // 重载后置++运算符, int代表占位参数,区分前置与后置递增 24 // 后置递增返回值,不能返回引用,因为是个局部变量,不能返回局部变量的引用 25 MyInteger operator++(int) { 26 // 先记录当时结果 27 MyInteger temp = *this; 28 29 // 后 递增操作 30 m_Num++; 31 // 最后,将记录的结果返回 32 33 return temp; 34 } 35 36 private: 37 int m_Num; 38 39 }; 40 41 // 全局函数实现“<<”运算符重载 42 ostream& operator<<(ostream& cout, MyInteger myint) { 43 cout << myint.m_Num; 44 return cout; 45 46 } 47 48 void test01() { 49 50 MyInteger myint; 51 52 cout << ++myint << endl; 53 54 } 55 56 void test02() { 57 MyInteger myint; 58 59 cout << myint++ << endl; 60 cout << myint << endl; 61 62 } 63 64 int main() { 65 66 //test01(); 67 test02(); 68 69 system("pause"); 70 71 return 0; 72 }
5.4 赋值运算符重载
1 #include<iostream> 2 using namespace std; 3 4 // 赋值运算符重载 5 class Person { 6 public: 7 Person(int age) { 8 m_Age = new int(age); 9 } 10 11 //重载 赋值运算符 12 Person& operator=(Person &p) { 13 //编译器提供的是如下的浅拷贝 14 // m_Age = p.m_Age; 15 16 //首先应该判断是否存在有属性在堆区,如果有,要先释放干啥,然后进行深拷贝 17 if (m_Age != NULL) { 18 delete m_Age; 19 m_Age = NULL; 20 } 21 22 // 然后进行深拷贝操作 23 m_Age = new int(*p.m_Age); 24 25 // 要返回对象本身 26 return *this; 27 28 } 29 30 ~Person() { 31 if (m_Age != NULL) { 32 delete m_Age; 33 m_Age = NULL; 34 } 35 } 36 37 int* m_Age; 38 }; 39 40 41 42 void test01() { 43 Person p1(18); 44 45 Person p2(20); 46 47 Person p3(30); 48 49 p2 = p1; // 赋值运算操作 50 51 p3 = p2 = p1; //注意返回值类型 52 53 cout << "p1的年龄为:" << *p1.m_Age << endl; 54 cout << "p2的年龄为:" << *p2.m_Age << endl; 55 cout << "p3的年龄为:" << *p3.m_Age << endl; 56 } 57 58 int main() { 59 60 test01(); 61 62 system("pause"); 63 64 return 0; 65 } 66 67 // 总结 68 // C++默认给一个类添加4个函数 69 // 默认构造,默认析构函数 70 // 默认拷贝(对属性进行值拷贝) 71 // 72 // 赋值运算符operator=对属性进行值拷贝 73 // 74 // 如果有属性指向堆区,做赋值操作时会出现深浅拷贝的问题 75 // 如果出现堆区数据,要通过深拷贝方法解决 76 //
5.5 关系运算符重载
1 #include<iostream> 2 using namespace std; 3 4 // 关系运算符重载 5 // 可以让自定义的两个类型对象进行对比操作 6 7 class Person { 8 public: 9 Person(string m_Name, int age) { 10 m_Age = age; 11 m_Name = m_Name; 12 } 13 14 //重载 == 号 15 bool operator==(Person& p) { 16 if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) { 17 return true; 18 } 19 return false; 20 } 21 22 string m_Name; 23 int m_Age; 24 25 }; 26 27 void test01() { 28 Person p1("Tom", 18); 29 30 Person p2("Tom", 18); 31 32 if (p1 == p2) { 33 cout << "p1和p2是相等的!" << endl; 34 35 } 36 37 } 38 39 int main() { 40 41 test01(); 42 43 system("pause"); 44 45 return 0; 46 }
5.6 函数调用运算符重载
1 #include<iostream> 2 using namespace std; 3 #include<string> 4 5 6 // 函数调用()运算符重载 7 // 由于重载后使用的方式非常想函数的调用,因此也成为“仿函数” 8 // 仿函数没有固定写法,非常的灵活 9 10 class MyPrint { 11 public: 12 void operator()(string text) { 13 cout << text << endl; 14 15 } 16 }; 17 18 class Myadd { 19 public: 20 int operator()(int a, int b) { 21 return a + b; 22 } 23 }; 24 25 void test01() { 26 // 重载的 () 操作符 也称为仿函数 27 MyPrint myfunc; 28 myfunc("hello world"); 29 30 // 匿名函数对象 31 cout << Myadd()(10, 20) << endl; 32 33 } 34 35 int main() { 36 37 test01(); 38 39 system("pause"); 40 41 return 0; 42 }
参考《黑马程序员》C++教程