基础

算术运算符满足左结合律,如果运算符的优先级相同,将按照从左向右的顺序组合运算对象。

运算对象的求值顺序与优先级和结合律无关,对于下面的表达式

  1. f() + g() * h() + j();
  • 优先级规定,g ( ) 的返回值和 h ( ) 的返回值相乘
  • 结合律规定,f ( ) 的返回值先与 g ( ) 和 h ( ) 的乘积相加,所得结果再与 j ( ) 的返回值相加
  • 对于这些函数的调用顺序没有明确规定

因此,如果改变了某个运算对象的值,在表达式的其他地方不要再使用这个对象

int i = 0;
cout << i << " " << ++i << endl;  // 错误,编译器不报错,但会产生未定义行为

例外:有四种运算符明确规定了运算对象的求值顺序

  • 逻辑与( && )运算符:先求左侧运算对象的值,只有在左侧运算对象的值为真时才继续求右侧运算对象的值
  • 逻辑或( | | )运算符
  • 条件( ? : )运算符
  • 逗号( , )运算符

    显示转换

    命名的强制类型转换

    一个命名的强制类型转换具有形式:cast-name(expression)

    static_cast

    任何具有明确定义的类型转换,只要不包括底层 const ,都可以使用 static_cast 。
    int i = 3, j = 2;
    double slope = static_cast<double>(i) / j;
    

    const_cast

    const_cast 只能改变运算对象的底层 const ,即去掉 const ,但不能改变对象类型。
    const char *cp;
    char *q = const_cast<char*>(cp);  // 正确
    char *q = static_cast<string>(cp);  // 正确,字符串字面值转换为 string 类型
    char *q = const_cast<string>(cp);  // 错误
    

    reinterpret_cast

    通常其运算对象的位模式提供较低层次上的重新解释,尽量不要使用。

    旧式的强制类型转换

    type (expr);  // 函数形式的强制类型转换
    (type) expr;  // C 语言风格的强制类型转换