1、加号运算符重载(加减乘除)
首先假设你有一个Person类,里面有个成员变量m_a和m_b,现在你想使p1+p2等价于p1.m_a+p2.m_a,p1.m_b+p2.m_b
class Person { public:Person() {};Person(int a, int b) : m_a(a), m_b(b) {}
// +运算需要两个操作数,一个是this,另一个需要传参Person operator+(const Person& p) {Person temp(0, 0);temp.m_a = this->m_a + p.m_a;temp.m_b = this->m_b + p.m_b;return temp;} public:int m_a;int m_b; };
C++提供了一种函数来重载各种运算符,即operator紧跟你要重载的运算符,以上的operator+是在类内重载加号运算符,可以通过以下方式调用:
Person p1(10, 20); Person p2(10, 20); Person p3 = p1 + p2;
触类旁通可以写出全局重载
// 直接传入两个相加的操作数
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; }
2.左移运算符重载
<<的作用是输出,比如cout << p << endl;
建议使用全局重载
// 返回类型为ostream的引用,是为了链式调用,即cout << p执行完后,返回当前cout,继续执行<<endl;
ostream& operator<<(ostream& cout, Person& p) {cout << "m_a = " << p.m_a << endl;cout << "m_b = " << p.m_b << endl;return cout; }
因为其重载的本质调用是operator<<(cout, p),可以简化为cout << p,这是正常顺序,而若是在类内重载,其实现如下:
ostream& operator<<(ostream& cout) {cout << "m_a = " << this->m_a << endl;cout << "m_b = " << this->m_b << endl;return cout; }
而其调用本质则为p.operator<<(cout),简化为p << cout,虽然可以用,但并不建议这么写:)
3、自增运算符重载(自减)
前自增
// ++(++a)也属于链式调用,所以要返回引用,使其返回本身
Person& operator++() {m_a++;m_b++;return *this; }
后自增
// (a++)++也属于链式调用,但因其“先输出后自增”的特点,使得在自增完成后返回的是自增前本身的副本,对于局部变量要返回值触发拷贝构造。
Person operator++(int) {//int占位Person temp = *this;m_a++;m_b++;return temp; }
4、赋值运算符重载
赋值运算符常见形式为Person p2 = p1,默认的赋值运算会将p1的成员变量一分不动的赋值到p2,也就是浅拷贝,若是有引用变量,则有可能导致析构函数内重复释放的问题,解决办法是手动重载赋值运算符为深拷贝。
// a = b = c,赋值的链式调用,也就是c赋值给b后返回自身b,再赋值给a,所以要返回引用类型 Person& operator=(Person& p) {if (p_data != NULL) {delete p_data;p_data = NULL:}p_data = new int(*p.p_data);return *this; }
5、比较运算符重载
bool operator==(Person& p) {// 比较返回 } bool operator!=(Person& p) {// 比较返回 }
6、函数调用运算符重载
即()运算符重载
void operator()(string text) {cout << text << endl; }
可以通过以下方式调用:
p("Hello");
因其类似函数调用,也被称为仿函数