4.1.1 基本概念
【C++ 定义了作用于不同数量运算对象的
一元运算符和
二元运算符,此外还有一个作用于三个运算对象的
三元运算符,
函数调用也是一种特殊的运算符,它对运算对象的数量没有限制。】
【当运算符作用于类类型的运算对象时,用户可以自行定义其含义。因为这种自定义的过程事实上是为已存在的运算符赋予了另外一层含义,所以称之为
重载运算符。
我们使用重载运算符时,其包括运算对象的类型和返回值的类型,都是由该运算符定义的;但是运算对象的个数、运算符的优先级和结合律都是无法改变的。】
【C++ 的表达式要不然是右值、要不然就是左值。左值可以位于赋值语句的左侧,右值则不能。
当一个对象被用作右值的时候,用的是对象的值(内容);当对象被用作左值的时候,用的是对象的身份(在内存中的位置)。
不同的运算符对运算对象(左值or右值)的要求不同,返回值也有差异。但一个重要的原则是:
在需要右值的地方可以用左值来代替,但是不能把右值当成左值使用。
使用decltype 的时候,左值与右值也有差异,2.5.3 介绍过。】
4.1.2 优先级与结合律
【复合表达式是指含有两个或多个运算符的表达式。
优先级与结合律决定了运算对象组合的方式,它们决定了表达式中每个运算符对应的运算对象来自表达式中的哪一部分。(括号无视优先级与结合律)
算数运算符满足左结合律,如果运算符的优先级相同,算术运算符将会按照从左向右的顺序组合运算对象。】
4.1.3 求值顺序
【优先级和结合律规定了运算对象的组合形式,但没有说明运算对象的求值顺序(尤其当某运算会改变对象的值时)。运算对象的求值顺序与优先级和结合律无关。
对于那些没有指定执行顺序的运算符来说,
如果表达式中使用了某一个对象且又同时存在修改该对象的运算,那么使用该对象是在操作之前还是操作之后是不明了的,将会引发错误并产生未定义的行为
。
有四种运算符明确规定了运算对象的求值顺序,它们是:逻辑与运算符(&&)、逻辑或运算符(||)、条件运算符(?:)、逗号运算符(,)。】
【
拿不准的时候最好用括号来强制让表达式的组合关系符合程序逻辑的要求(针对优先级和结合律搞不懂);
如果改变了某个运算对象的值,在表达式的其他地方不要再使用这个运算对象(针对未明确的求值顺序)。】