对于内置的数据类型,编译器知道如何运算。但是对于自定义数据类型,编译器不知道怎么运算。因此,才衍生出了运算符重载。
1、加号运算符重载;
一种方式通过成员函数重载,另一种通过全局函数重载。
1 class Person{ 2 public: 3 //通过成员函数重载+ 4 /*Person operator+(Person &p){ 5 Person temp; 6 temp.m_A = this->m_A + p.m_A; 7 temp.m_B = this->m_B + p.m_B; 8 return temp; 9 }*/ 10 int m_A; 11 int m_B; 12 }; 13 //通过全局函数重载加号 14 Person operator+(Person &p1, Person &p2){ 15 Person temp; 16 temp.m_A = p1.m_A + p2.m_A; 17 temp.m_B = p1.m_B + p2.m_B; 18 return temp; 19 } 20 Person operator+(Person &p1, int i){ 21 Person temp; 22 temp.m_A = p1.m_A + i; 23 temp.m_B = p1.m_B + i; 24 return temp; 25 26 } 27 void test01(){ 28 Person p1; 29 p1.m_A = 10; 30 p1.m_B = 10; 31 Person p2; 32 p2.m_A = 10; 33 p2.m_B = 10; 34 Person p3; 35 p3 = p1 + p2; 36 Person p4; 37 //p4 = p1 + 10; 简化 38 p4 = operator+(p1, 100); 39 cout << p3.m_A <<" "<< p3.m_B << endl; 40 cout << p4.m_A << " " << p4.m_B << endl; 41 }
2、左移运算符重载
如果想直接输出自定义对象,只能用全局函数重载左移运算符,用成员函数重载左移运算符不能实现cout在左边。
1 #include<iostream> 2 using namespace std; 3 class Person{ 4 friend ostream & operator<<(ostream &cout, Person &p); 5 public: 6 Person(int a,int b){ 7 m_A = a; 8 m_B = b; 9 } 10 private: 11 12 int m_A; 13 int m_B; 14 }; 15 ostream & operator<<(ostream &cout,Person &p){ 16 cout << p.m_A <<" " << p.m_B ; 17 return cout; 18 } 19 void test01(){ 20 Person p1(10,20); 21 cout << p1 << endl; //链式编程思想 22 } 23 int main(){ 24 test01(); 25 system("pause"); 26 }
3、递增运算符重载
1 #include<iostream> 2 using namespace std; 3 class MyInteger{ 4 friend ostream & operator<<(ostream &out, MyInteger &p); 5 public: 6 MyInteger(){ 7 m_Int = 0; 8 } 9 //重载前置++运算符 10 MyInteger & operator++(){ 11 m_Int++; 12 return *this; 13 } 14 //重载后置++运算符 15 MyInteger operator++(int){//int表示占位参数,可以用于区分前置和后置 16 //先记录 17 MyInteger temp = *this; 18 //递增 19 m_Int++; 20 //返回记录 21 return temp; 22 } 23 24 private: 25 int m_Int; 26 }; 27 //重载左移运算符 28 ostream & operator<<(ostream &out, MyInteger &p){ 29 cout << p.m_Int; 30 return out; 31 } 32 void test01(){ 33 MyInteger myint; 34 cout << ++(++myint) << endl; 35 cout << myint << endl; 36 } 37 void test02(){ 38 MyInteger p1; 39 cout << p1++ << endl; 40 cout << p1 << endl; 41 } 42 int main(){ 43 /*test01();*/ 44 test02(); 45 system("pause"); 46 }
后置++,返回值不能是引用,因为temp是一个局部变量,当函数执行完毕temp被释放,再对temp进行操作就是非法的。
4、赋值运算符重载。
编译器会给一个类至少添加四个函数:
a.默认的构造函数;(空实现)
b.默认析构函数;(空实现)
c.默认拷贝构造函数;(简单值拷贝)
d.赋值运算符operator=,对属性进行值拷贝。
1 #include<iostream> 2 using namespace std; 3 class Person{ 4 public: 5 Person(int age){ 6 m_Age=new int(age);//堆区手动释放 7 } 8 9 ~Person(){ 10 if (m_Age!=NULL) 11 { 12 delete m_Age; 13 m_Age = NULL; 14 } 15 } 16 //重载赋值运算符 17 Person & operator = (const Person &p){ 18 //先把堆区的属性释放干净,然后再深拷贝 19 if (m_Age!=NULL) 20 { 21 delete m_Age; 22 m_Age = NULL; 23 } 24 //编译器提供 m_Age = p.m_Age; 25 m_Age = new int(*p.m_Age);//深拷贝 26 return *this; 27 } 28 int *m_Age; 29 }; 30 void test01(){ 31 Person p1(18); 32 Person p2(20); 33 Person p3(1); 34 p3=p1 = p2;//赋值 会重复释放 35 cout << *p2.m_Age << endl; 36 cout << *p3.m_Age << endl; 37 38 } 39 int main(){ 40 test01(); 41 system("pause"); 42 }
以上重载赋值运算符严格来说是有问题的,假设一个特殊情况,p1=p1,自我赋值,如果一上来就执行第19行代码,m_Age所指的空间已经释放了,后面如何进行深拷贝?
修改后的写法
Person &operator=(const Person&p) { if(&p==this) //自我赋值检查 { return *this; } delete m_Age; m_Age=new int(*p.m_Age); return *this; }
5、关系运算符重载
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 class Person { 5 public: 6 Person(string name,int age){ 7 m_name = name; 8 m_Age = age; 9 } 10 bool operator==(Person &p){ 11 if (this->m_Age == p.m_Age && this->m_name == p.m_name) 12 { 13 return true; 14 } 15 else 16 { 17 return false; 18 } 19 } 20 bool operator!=(Person &p){ 21 if (this->m_Age != p.m_Age || this->m_name != p.m_name){ 22 return true; 23 } 24 else 25 { 26 return false; 27 } 28 } 29 string m_name; 30 int m_Age; 31 }; 32 void test01(){ 33 Person p1("tom", 18); 34 Person p2("tom", 18); 35 if (p1==p2) 36 { 37 cout << "p1和p2相等" << endl; 38 } 39 else if (p1!=p2) 40 { 41 cout << "不相等" << endl; 42 } 43 44 } 45 int main(){ 46 test01(); 47 system("pause"); 48 }
6、重载小括号
又称仿函数。
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 class Myprint{ 5 public: 6 void operator()(string test) 7 { 8 cout << test << endl; 9 } 10 }; 11 int main() 12 { 13 Myprint print; 14 print("hello world"); 15 system("pause"); 16 }
 
                    
                     
                    
                 
                    
                 
                
            
         
         
 浙公网安备 33010602011771号
浙公网安备 33010602011771号