问题的历史:
在 C++ 语言中,表达式和运算符是基础构建块,早在 C 语言中就已存在。C++ 支持广泛的各类运算符:算术、逻辑、位、比较、赋值,以及三元运算符和逗号运算符。随着语言的发展,运算符变得可以被重载,这扩展了编写表达式和简洁代码的可能性。
问题:
正确构建表达式和理解其执行顺序常常使开发者感到困扰,尤其是在包含多个优先级和运算符关联性的复杂表达式中。错误可能导致计算结果含义的改变、不必要的副作用,甚至是未定义的行为。
解决方案:
为了确保程序可靠运行,重要的是要很好地理解运算符的优先级、它们的关联性以及类型(单目、双目、三元、左/右)。在大多数情况下,建议明确用括号分组操作,并避免滥用复杂表达式。对于用户自定义类型,允许根据最少且明显必要的逻辑原则重载运算符。
代码示例:
#include <iostream> class Point { public: int x, y; Point(int x, int y) : x(x), y(y) {} Point operator+(const Point& other) const { return Point(x + other.x, y + other.y); } }; int main() { Point a(1, 2), b(3, 4); Point c = a + b; std::cout << c.x << ", " << c.y << std::endl; // 4, 6 int d = 1 + 2 * 3; // 7, 而不是 9! return 0; }
关键特性:
可以重载逗号运算符吗?如果可以,这在什么情况下会有用?
是的,逗号运算符可以重载,但几乎不被使用,因为这几乎总会降低代码的可读性。在某些特定的容器中可以看到重载的例子,以实现调用链。
表达式 1 + 2 << 3 的计算结果是多少?为什么?
表达式的计算方式为:首先计算 2 << 3(左位移,结果为 16),然后计算 1 + 16(总共 17),因为 << 的优先级低于加法。
int result = 1 + 2 << 3; // 结果:17,而不是 24!
表达式的类型(有符号/无符号)如何影响比较结果,例如,-1 < 1u?
当将有符号与无符号值进行比较时,会发生转换为无符号类型,-1 变为一个很大的正数,因此比较结果为 false。
std::cout << (-1 < 1u) << std::endl; // 输出 0 (false)
开发者重载了 Complex 类的 ''+'' 运算符,以便与 int 相加,隐含地改变了求和的逻辑,忽略了优先级。编译器允许了,但结果错误地将实部与整数相加,导致计算中的漏洞。
优点:
缺点:
运算符仅重载用于与另一个 Complex 相加。在文档中明确说明了支持的操作,所有表达式都进行了明确分组。
优点:
缺点: