Talk is cheap,show you the code.
class Node{
public:
int x;
Node(int x){
this->x = x;
}
Node& operator++(){
x++;
return *this;
}
Node operator++(int){
Node ans = *this;
x++;
return ans;
}
};
现象
- 返回值类型不同
- 参数类型不同,那个int并无卵用,只是为了区分前置还是后置
运算符和函数
- 任何运算符都相当于一种函数,加减乘除+-*/是二元函数,!(非)~(取反)是一元函数
- 如果一个函数太常见了,太常用了,那么人们就更习惯于把它写成运算符.
- 运算符多了,就产生了优先级和结合性这种衍生品,符号的优先级和结合性是常识,人虽然通过将函数用运算符代替,简化了写法,却又带来了新的知识,这是运算符的缺点.
- 运算符不可能太多,假如有100个运算符,那么运算符优先关系相当于100*100的矩阵,记不下来的.虽然使用运算符可能简化书写,却又带来了优先级和结合性的混乱.
- 于是函数的优势就太明显了
- 书写统一,都是fun(x,y...)形式的
- 字符串已经从语义上表达了这个函数的作用,而运算符,没人知道你要用奇怪的符号来表示什么
- 字符串便于输入,便于书写,但难于阅读
mul(add(3,div(57,3)),sub(7,add(5,6))哪里比得上(3+57/3)*(7-(5+6))这样清晰简练,但是函数方式不需要考虑优先级.四则运算表达式需要解析一下才能开始正式的函数调用.
- 函数的本质是集合上的映射,硬件是集合上的元素,软件是关系
- 写成函数需要多写好几个字符
- 写成运算符可读性比较好,4/3比div(4,3)要清楚一点
- 运算符有一种几何关系,x?y:z;这是一个三元运算符,符号把它们隔开形成一种像图画一样的东西,高数上的积分符号等都是如此.
- 符号具有图画的特征,而字符串具有通用易输入的特征.
- 翻译成汇编语言之后,都相当于函数,每条语句只执行一个函数
- 运算符要少而精,要符合常识.剩下的都用函数来代替.这正是java中没有运算符重载的原因.
- 一个比较好的例子
int x=4;
cout<<x++<<++x<<endl;
输出56
为什么呢?
- <<是一种运算符,相当于一种二元运算符.
ostream& operator<<(ostream&o, Node&no){
o << no.x;
return o;
}
- 上面那句cout<<x++<<++x<<endl; 就相当于
print(print(print(cout,x++),++x),endl)- 翻译成汇编语言一目了然
++x;
y=x++;
cout<<y;
cout<<x;
cout<<endl;
- 可见,先执行的++x,x就变成了5.再执行的x++,x就变成了6.
本质
- 后置运算符x++,先把本体保存到临时变量里,然后更改本体,最后返回那个临时变量.
- 这个临时变量只用一次,理论上(常识上)应该是const型的,但是不加const也对.
- 前置运算符需要调用复制构造函数,开辟新的空间,所以比较浪费时间,浪费空间.
- 普通变量的复制还好,若是一个类,那可就麻烦了.开辟一个大大的空间,用memcpy复制过去,浪费很多空间,很多时间
- 前置运算符++x,先更改本体,改完之后直接返回本体.
- 前置运算符运行比较快,毕竟不需要进行备份.