运算符重载是C++的重要特性之一,它允许程序员自定义非标准类对象使用运算符时,运算符是应该如何运算。作者在学习左移运算符重载时,老师说左移运算符函数尽量不要写到类中,而是作为全局函数使用,但没有多做解释。本文将分析这是为什么。作者是小白,希望大佬看到有错误的地方能够指出,也欢迎大家讨论。
左移运算符与加减乘除无异,都是在c++中都是双目运算符。不同于C语言,C++的左移运算符不局限于二进制位操作,而是赋予了其新的含义,作为标准输入输出流(iostream)连接符使用。我们之前在学习加法的运算符重载时,并未明确提到一个问题:事实上操作数是有顺序的。以加法运算符重载为例:
#include <iostream>
using namespace std;
class Person{
public:
Person(){
m_age = 18;
Person operate+();
}
private:
int m_age;
};
Person Person::operate+(Person& p){
Person temp;
temp->m_age = this->m_age+p.m_age;
return temp;
}
int main(void){
Person p1;
Person p2;
Person p3 = p1+p2; //原理是p3 = p1.operate+(p2)
return 0;
}
p3 = p1+p2和p3 = p2+p1在底层实现是有区别的,第一个是p1对象的成员函数,第二个是p2对象的成员函数。加法满足交换律,因此谁在前答案都是不变的。但是<<不同,他是有顺序的。
operate<<如果写在类中作为类的成员函数,那在调用时就只能p1.operate<<(cout)了。与加法相同,这是p1<<cout的底层实现——老实说这挺怪异的,不太符合我们使用cout的习惯。
而写在全局里作为全局函数就不会这样。函数operate(ostream& cout,Person& p)的实现可以指定p1和cout的顺序。顺便一提,操作符重载函数体类似于作替换,cout<<p1将被替换成cout<<p1.m_age;具体看实现。