C++运算符重载的基本规则

运算符重载必须遵循以下核心规则:

  • 重载的运算符至少有一个操作数是用户定义类型(类或枚举类型)
  • 不能创建新的运算符,只能重载现有运算符
  • 不能改变运算符的优先级和结合性
  • 不能改变运算符的操作数个数(如二元运算符不能重载为一元运算符)

可重载的运算符分类

大多数C++运算符可以重载,包括:

  • 算术运算符:+ - * / %
  • 关系运算符:== != < > <= >=
  • 逻辑运算符:&& || !
  • 位运算符:& | ^ ~ << >>
  • 赋值运算符:= += -=
  • 其他运算符:[] () -> new delete ,

不可重载的运算符包括:

  • 成员访问运算符:.
  • 成员指针运算符:.*
  • 作用域解析运算符:::
  • 条件运算符:?:
  • sizeoftypeid运算符

成员函数与非成员函数重载

运算符可以通过成员函数或非成员函数重载,但有些运算符必须作为成员函数:

必须作为成员函数重载的运算符:

  • 赋值运算符:=
  • 函数调用运算符:()
  • 下标运算符:[]
  • 成员访问运算符:->

典型成员函数重载示例:

class Vector {
public:
    Vector operator+(const Vector& other) const {
        return Vector(x + other.x, y + other.y);
    }
private:
    int x, y;
};

典型非成员函数重载示例:

class Vector {
    friend Vector operator+(const Vector& a, const Vector& b);
};

Vector operator+(const Vector& a, const Vector& b) {
    return Vector(a.x + b.x, a.y + b.y);
}

特殊运算符的重载规则

赋值运算符=

  • 如果不显式定义,编译器会生成默认的按成员拷贝
  • 需要处理自赋值情况
  • 通常返回*this的引用

下标运算符[]

  • 通常需要提供const和非const两个版本
  • 可以用于创建类似数组访问的接口

函数调用运算符()

  • 使对象可以像函数一样被调用
  • 常用于函数对象(functor)

输入输出运算符<<>>

  • 必须作为非成员函数重载
  • 通常声明为类的友元函数

运算符重载的最佳实践

保持运算符的直观语义:

  • 运算符行为应与内置类型类似
  • 避免违反直觉的实现(如+执行减法操作)

考虑异常安全性:

  • 运算符实现中要正确处理异常

返回值优化:

  • 对于创建新对象的运算符,考虑返回值优化(RVO)

重载一致性:

  • 相关运算符应一起重载(如==!=<>等)
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐