MST

星途 面试题库

面试题:C++ 中运算符重载时常见错误及处理方式

在 C++ 中进行运算符重载时,可能会遇到哪些常见错误?请至少列举三种,并阐述如何处理这些错误。
18.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 忘记返回值类型
    • 错误描述:在重载运算符函数定义时,忘记指定返回值类型。例如在重载+运算符时:
// 错误示例
operator+(const MyClass& a, const MyClass& b) {
    MyClass result;
    // 进行相加操作
    return result;
}
  • 处理方法:正确指定返回值类型。对于二元运算符+,通常返回一个新的对象,示例如下:
MyClass operator+(const MyClass& a, const MyClass& b) {
    MyClass result;
    // 进行相加操作
    return result;
}
  1. 参数数量错误
    • 错误描述:对于一元运算符,可能传入了过多参数;对于二元运算符,可能传入参数不足或过多。例如,重载一元-运算符时传入两个参数:
class MyClass {
public:
    // 错误示例
    MyClass operator-(const MyClass& a, const MyClass& b) {
        MyClass result;
        // 执行减法操作
        return result;
    }
};
  • 处理方法:一元运算符重载函数若作为成员函数,无参数;若作为非成员函数,有一个参数。二元运算符重载函数若作为成员函数,有一个参数;若作为非成员函数,有两个参数。正确的一元-运算符重载(非成员函数)示例如下:
class MyClass {
    // 类成员定义
};
MyClass operator-(const MyClass& a) {
    MyClass result;
    // 执行减法操作
    return result;
}
  1. 递归调用问题
    • 错误描述:在重载运算符函数内部,不小心导致递归调用。比如在重载<<运算符用于输出对象时:
std::ostream& operator<<(std::ostream& os, const MyClass& obj) {
    // 错误示例,假设MyClass有一个成员函数print自身
    obj.print(os);
    // 又调用了operator<<,导致递归
    os << obj;
    return os;
}
  • 处理方法:确保在重载运算符函数内部不会意外地再次调用该重载运算符函数。在上述<<运算符重载中,去掉多余的os << obj调用即可。
  1. 违反运算符原有语义
    • 错误描述:重载运算符时,实现的功能与运算符原有的语义相差过大,导致代码可读性和可维护性变差。例如,将+运算符重载为执行除法操作:
MyClass operator+(const MyClass& a, const MyClass& b) {
    MyClass result;
    // 用a的某个成员除以b的某个成员
    result.member = a.member / b.member;
    return result;
}
  • 处理方法:尽量保持运算符原有的语义。如果+运算符重载,应实现类似加法的逻辑,如将两个对象的对应成员相加等。
  1. 未正确处理左值和右值
    • 错误描述:在重载赋值运算符=时,没有正确处理自赋值情况,或者在移动语义相关的运算符重载(如移动赋值=)中没有正确处理右值引用。例如,在赋值运算符=重载中:
MyClass& MyClass::operator=(const MyClass& other) {
    if (this == &other) {
        // 没有处理自赋值直接返回
        return *this;
    }
    delete[] data;
    data = new char[strlen(other.data) + 1];
    strcpy(data, other.data);
    return *this;
}
  • 处理方法:在赋值运算符重载中,先检查自赋值情况,然后再进行资源释放和重新分配等操作。在移动语义相关的运算符重载中,正确处理右值引用,例如移动赋值运算符:
MyClass& MyClass::operator=(MyClass&& other) noexcept {
    if (this == &other) {
        return *this;
    }
    delete[] data;
    data = other.data;
    other.data = nullptr;
    return *this;
}