四则运算符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Person { public: Person() {}; Person(int a, int b) { this->m_A = a; this->m_B = b; }
Person operator+(const Person& p) { Person temp; temp.m_A = this->m_A + p.m_A; temp.m_B = this->m_B + p.m_B; return temp; } private: int m_A; int m_B; };
|
1 2 3 4 5 6 7 8 9
| Person operator+(const Person& p1, const Person& p2) { Person temp(0, 0); temp.m_A = p1.m_A + p2.m_A; temp.m_B = p1.m_B + p2.m_B; return temp; }
Person p = p1 + p2;
|
1 2 3 4 5 6 7 8 9 10
| Person operator+(const Person& p2, int val) { Person temp; temp.m_A = p2.m_A + val; temp.m_B = p2.m_B + val; return temp; }
Person p = p1 + 10;
|
本质调用
1 2 3 4
| Person p = p1.operator+(p2);
Person p = operator+(p1, p2);
|
其他运算符和 +
类似,只是注意精度别爆 int
以及除法特判除数为 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
| class Person { friend ostream& operator<<(ostream& out, Person& p); public: Person(){} Person(int a, int b) { this->m_A = a; this->m_B = b; } private: int m_A; int m_B; };
ostream& operator<<(ostream& cout, Person& p) { cout << "a:" << p.m_A << " b:" << p.m_B; return out; }
|
1 2 3 4 5 6 7
| ostream& operator<<(ostream& out, Person& p) { out << "a:" << p.m_A << " b:" << p.m_B; return out; }
cout << p;
|
- 注意传参和返回值都需要引用的存在
- 因为标准输出流对象只能有一个,所以不能创建副本,返回值自然也不能传值
- 返回值传引用是因为
- 调用过程是:执行
cout << p
,左移运算符做了重载,传入 cout
和 p
- 然后执行函数体,就实现了重载,这里相当于是
ostream& out = cout
为了实现链式编程,返回值为 ostream&
,这样之后就可以 cout << p << endl
递增运算符
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
| class MyInteger { friend ostream& operator<<(ostream& out, MyInteger myint); public: MyInteger() { m_Num = 0; } MyInteger& operator++() { m_Num++; return *this; } MyInteger operator++(int) { MyInteger temp = *this; m_Num++; return temp; } private: int m_Num; };
ostream& operator<<(ostream& out, MyInteger myint) { out << myint.m_Num; return out; }
MyInter a; cout << ++(++a); cout << a++;
|
- 前置加加返回引用是因为存在
++(++a)
这种情况,我们要实现这种,就需要返回引用
- 因为不返回引用,第一次
++a
后是创建的一个副本即新对象作为 ++a
的结果,那么此时再执行 ++a
虽然能够使 ++(++a)
得到正确的结果,但是 a
却不是,因为第二次的加加不是在 a
基础上的加,是一个新的副本
- 值返回不能是因为不能返回局部引用,第二种方式会构造局部引用
赋值运算符
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
| class Person { public: Person() : m_age(nullptr){} Person(int age) { m_Age = new int(age); }
Person& operator=(const Person &p) { if (m_Age != NULL) { delete m_Age; m_Age = NULL; }
m_Age = new int(*p.m_Age);
return *this; }
~Person() { if (m_Age != NULL) { delete m_Age; m_Age = NULL; } } private: int *m_Age; };
Person p1(10); Person p2, p3; p3 = p2 = p1;
|
- 注意实例化对象不初始化,需要在默认构造函数里指针指向空,不然是野指针,随意指向一块空间,此时进入拷贝构造函数,就会释放非法内存,导致崩溃
- 这是应对指针的拷贝构造函数,默认拷贝构造会造成释放同一块内存区域的问题,导致出错
- 对于这种类型的传引用,使用
const
修饰会更好,防止意外修改
关系运算符
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
| class Person { public: Person(string name, int age) { this->m_Name = name; this->m_Age = age; }; bool operator==(const Person & p) { if (this->m_Name == p.m_Name && this->m_Age == p.m_Age) { return true; } else { return false; } } string m_Name; int m_Age; };
Person a("孙悟空", 18); Person b("孙悟空", 18); if(a == b) else if(a != b)
|
函数调用运算符 ( )
1 2 3 4 5 6 7 8 9 10
| class MyPrint { public: void operator()(string text) { cout << text << endl; } };
MyPrint myFunc; myFunc("hello world");
|
1 2 3 4 5 6 7 8 9 10
| class MyAdd { public: int operator()(int v1, int v2) { return v1 + v2; } };
MyAdd add; int ret = add(10, 10);
|


xingzhu
keep trying!keep doing!believe in yourself!
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 星竹!