3.1 基础
运算符重载:
使用重载运算符的时候,包括运算对象的类型和返回值的类型,都是由该运算符定义的,但是运算对象的个数,运算符的优先级和结合律都是无法改变的。
左值与右值:
当一个对象被用作右值的时候,用的是对象的值(内容),当对象被当做左值的时候,用的是对象的身份。
在需要右值的地方可以用左值来代替,但是不能把右值当做左值使用。
使用关键字decltype的时候,如果表达式的求值结果是左值,decltype作用于该表达式得到一个引用类型。
求值顺序:(不同于结合律)
c++中只规定了运算对象的组合方式和结合律,但是没有说明运算对象按照什么顺序求值。
比如: int i = f1() * f2(); (结合律为从左到右【相同优先级下】)
不清楚是先运行f1函数还是先运行f2函数。
对于那些没有指定执行顺序的运算符来说,如果表达式指向并修改了同一对象,将会引发错误并产生未定义的行为。比如:
cout<<i<<" "<<++i<<endl;
并不清楚应该先调用++i还是i
只有4种运算符明确规定了运算对象的求值顺序,(1)&&(2)||(3)?:(4),
**除法和%标准** :
(-m) / n 和 m / (-n) 都等于 -(m / n)
m % ( -n ) = m%n , ( -m ) % n = -( m % n ) //符号同第一个数原则
短路求值:
&&,当且仅当左侧运算符为真的时候才会对右侧运算对象求值。
||,当且仅当左侧运算对象为假时才对右侧运算对象求值。
赋值运算符:
赋值运算符不同于初始化
赋值运算的结果是它的左侧运算对象,并且是一个左值。
赋值运算满足右结合律。
指针只可以赋值给相同的指针类型,除非强制转换。
自增(减):
前置版本将对象本身(加完后)作为左值返回,后置版本则将对象原始值的副本作为右值返回。
i=1;
++i=4; //i=4
i++=4; //错误
.和->运算符:
箭头运算符作用于一个指针类型的运算对象,结果是一个左值。点运算符分成两种情况:如果成员所属的对象是左值,那么结果是左值;反之,如果成员所属的对象是右值,那么结果是右值。
条件运算符?::
当条件运算符的两个表达式都是左值或者能转换成同一种左值类型时,运算的结果是左值,否则运算的结果是右值。
移位运算符:
满足左结合律,但是不会规定计算顺序
sizeof运算符:
满足右结合律,有两种形式的用法
sizeof(type) || sizeof(expr)
sizeof运算符并不实际计算其运算对象的值。对解引用的指针运算得到指针指向的对象所占空间的大小,指针不需要有效。
对数组运算将得到整个数组所占空间的大小,不会将数组转换为指针来处理,想要得到数组中的元素个数可以再除一个元素的大小。
逗号运算符:
从左到右的顺序依次求值