- 运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
加号运算符重载
实现两个自定义数据类型相加的运算。
对于内置的数据类型的表达式不能改变。
不能滥用运算符重载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| #include<iostrean> #include<string> using namespace std; class Person{ public: 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 test1(){ Person p1; p1.m_a = 10; p1.m_b = 10; Person p2; p2.m_a = 10; p2.m_b = 10;
Person p3 = p1 + p2; cout<< p3.m_a,p3.m_b << endl; Person p4 = p1 + 10; }
int main(){ test1() system("pause"); return 0; }
|
左移运算符重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include<iostrean> #include<string> using namespace std; class Person{ public: int m_a; int m_b; }
ostream & operator<<(ostream &cout,Person &p){ cout<< p.m_a << p.m_b; return cout; }
void test1(){ Person p; p.m_a = 10; p.m_b = 10; cout<< p << endl; }
int main(){ test1() system("pause"); return 0; }
|
递增运算符重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include<iostrean> using namespace std; class MyInteger{ public: MyInteger(){ num = 0; } MyInteger& operator++(){ num++; return *this; } MyInteger operator++(int){ MyInteger tmp = *this; num++; return tmp; } private: int num; }
ostream& operator<<(ostream& cout, MyInteger& myint){ cout << myinit.num; return cout; }
int main(){
MyInteger myinit; cout << ++(++myint) << endl; cout << myinit << endl; system("pause"); return 0; }
|
赋值运算符重载
C++编译器至少给一个类添加4个函数:
- 默认构造函数(无参,函数体为空)
- 默认析构函数(无参,函数体为空)
- 默认拷贝构造函数,对属性进行值拷贝
- 赋值运算符operator=,对属性进行值拷贝
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题。
- 编译器默认提供的复制运算符为浅拷贝。
- 当有数据存储在堆区的时候就会出现重复释放的问题,所以需要重新对复制运算符进行重载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #include<iostrean> 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; }
int main(){ Person p1(18); Person p2(20); Person p3(30); p3 = p2 = p1; cout<< *p1.m_age << *p2.m_age << *p3.m_age <<endl; system("pause"); return 0; }
|
关系运算符重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include<iostrean> #include<string> using namespace std;
class Person{ public: Person(string name, int age){ m_name = name; m_age = age; } bool operator==(Person &p){ if(this->n_name == p.m_name && this->m_age == p.m_age){ return true; } return false; } bool operator==(Person &p){ if(this->n_name == p.m_name && this->m_age == p.m_age){ return false; } return true; } string m_name; int m_age; }
void test(){ Person p1("Tom",18); Person p2("Tom",18); if(p1==p2){ cout<< "p1=p2" <<endl; } }
int main(){ test(); system("pause"); return 0; }
|
函数调用运算符重载
- 函数调用运算符()也可以重载。
- 由于重载后使用的方式非常像函数的调用,因此称为仿函数
- 仿函数没有固定写法,非常灵活
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include<iostrean> #include<string> using namespace std;
class MyPrint{ public: void operator()(string test){ cout << test << endl; } } int main(){ MyPrint myPrint; myPrint("Hello World"); cout<< MyAdd()('Hello C++ !') << endl; system("pause"); return 0; }
|