面试题答案
一键面试提升代码可读性示例
在C++中,对于自定义类重载加法运算符(+)可以使代码更符合自然语言表达习惯,从而提升可读性。例如,有一个表示二维向量的类Vector2D
,重载加法运算符后,两个向量相加的操作就如同数学运算一样直观。
以下是代码实现:
#include <iostream>
class Vector2D {
public:
int x;
int y;
Vector2D(int a = 0, int b = 0) : x(a), y(b) {}
// 重载加法运算符
Vector2D operator+(const Vector2D& other) const {
return Vector2D(x + other.x, y + other.y);
}
};
int main() {
Vector2D v1(1, 2);
Vector2D v2(3, 4);
Vector2D result = v1 + v2;
std::cout << "Result x: " << result.x << ", Result y: " << result.y << std::endl;
return 0;
}
在上述代码中,v1 + v2
这种写法比调用一个类似addVectors(v1, v2)
的函数更加直观,很容易理解这是在进行向量的加法操作。
语法规则
- 函数声明:重载运算符函数的声明形式为
返回类型 operator运算符符号(参数列表)
。例如Vector2D operator+(const Vector2D& other) const
,返回类型是自定义类类型,参数列表根据运算符特性确定,这里二元运算符+
有一个参数。 - 成员函数与友元函数:
- 成员函数:像上述代码中的重载
+
运算符,作为Vector2D
类的成员函数,第一个操作数就是调用该函数的对象本身(通过this
指针隐式传递)。 - 友元函数:也可以将重载运算符定义为类的友元函数,此时参数列表中需要显式列出所有操作数。例如,若将
+
运算符重载为友元函数:
- 成员函数:像上述代码中的重载
class Vector2D {
public:
int x;
int y;
Vector2D(int a = 0, int b = 0) : x(a), y(b) {}
friend Vector2D operator+(const Vector2D& a, const Vector2D& b);
};
Vector2D operator+(const Vector2D& a, const Vector2D& b) {
return Vector2D(a.x + b.x, a.y + b.y);
}
- 保持运算符的基本语义:重载运算符应尽量保持其原有的语义。例如
+
运算符通常表示相加的含义,不要赋予其与加法无关的语义。
潜在问题
- 运算优先级:C++中运算符有既定的优先级,重载运算符不能改变这种优先级。例如
a + b * c
,乘法运算符*
的优先级高于加法运算符+
,即使重载了+
和*
运算符,优先级依然不变。 - 运算符结合性:同样,重载运算符也不能改变运算符的结合性。例如加法运算符
+
是左结合的,即a + b + c
等同于(a + b) + c
。 - 不适当的重载:避免过度重载运算符导致代码语义混乱。例如不要将
+
运算符重载为减法操作,这样会使代码可读性变差。 - 递归调用问题:在重载运算符函数中,要注意避免递归调用导致栈溢出。例如,在重载
+
运算符时,如果在函数内部又通过+
运算符调用自身而没有适当的终止条件,就会出现这种问题。