云计算百科
云计算领域专业知识百科平台

深入理解C++ 重载 <四> 重载加号运算符

在 C++ 中,重载 + 运算符的本质是定义一个名为 operator+ 的函数。它通常用于让自定义类型支持类似内置类型的加法写法,例如:

cpp

Point a(1, 2);
Point b(3, 4);
Point c = a + b; // 希望得到 (4, 6)

+ 既可以重载为成员函数,也可以重载为非成员函数。二元 + 的两种基本形式如下。


1. 成员函数形式

在类内声明:

cpp

class Point {
public:
Point operator+(const Point& rhs) const;
};

含义:

  • 左操作数是当前对象 *this;

  • 右操作数是参数 rhs;

  • const 表示不会修改当前对象;

  • 返回类型通常是新对象 Point,而不是引用;

  • a + b 等价于 a.operator+(b)。

实现:

cpp

Point Point::operator+(const Point& rhs) const {
return Point(x_ + rhs.x_, y_ + rhs.y_);
}

注意:

  • 参数用 const Point&,避免拷贝,也表明不修改右操作数;

  • 返回值用 Point,因为 a + b 产生一个临时新对象;

  • 不要返回局部对象的引用,否则会悬空。


2. 非成员函数形式

也可以写成类外函数:

cpp

Point operator+(const Point& lhs, const Point& rhs);

如果该函数需要访问 Point 的私有成员,可以在类内声明为友元:

cpp

class Point {
friend Point operator+(const Point& lhs, const Point& rhs);
};

实现:

cpp

Point operator+(const Point& lhs, const Point& rhs) {
return Point(lhs.x_ + rhs.x_, lhs.y_ + rhs.y_);
}

非成员函数的好处是左右操作数地位对称。例如如果 Point 有非 explicit 的构造函数,那么 5 + p 和 p + 5 都可能支持。成员函数形式通常要求左操作数已经是 Point 类型。

但注意:不要同时对同一个类型定义成员版和非成员版的同一个 operator+,否则 a + b 会产生二义性。


3. 关键规则

  • 不能改变运算符的优先级、结合性和操作数个数。

  • 不能重载内置类型之间的 +,例如 int operator+(int, int) 是非法的。

  • 至少有一个操作数必须是用户定义类型或枚举类型。

  • operator+ 通常不修改操作数,返回一个新对象。

  • 如果是成员函数,建议加 const,否则 const Point 对象无法使用 +。

  • 参数建议用 const T&,避免不必要的拷贝。

  • 返回值建议用值类型 T,而不是 T&。

  • 通常可以先实现 operator+=,再基于它实现 operator+,但简单场景直接构造新对象即可。

  • #include <iostream>

    class Point {
    public:
    Point(int x = 0, int y = 0) : x_(x), y_(y) {}

    // 重载二元 +:成员函数版本
    // a + b 等价于 a.operator+(b)
    Point operator+(const Point& rhs) const {
    return Point(x_ + rhs.x_, y_ + rhs.y_);
    }

    // 重载 +=:修改当前对象,返回自身引用
    Point& operator+=(const Point& rhs) {
    x_ += rhs.x_;
    y_ += rhs.y_;
    return *this;
    }

    int x() const { return x_; }
    int y() const { return y_; }

    private:
    int x_;
    int y_;
    };

    // 重载输出运算符,方便打印
    std::ostream& operator<<(std::ostream& os, const Point& p) {
    os << "(" << p.x() << ", " << p.y() << ")";
    return os;
    }

    int main() {
    Point a(1, 2);
    Point b(3, 4);

    Point c = a + b; // 调用 a.operator+(b)
    std::cout << "a = " << a << '\\n';
    std::cout << "b = " << b << '\\n';
    std::cout << "a + b = " << c << '\\n';

    // 支持链式加法
    Point d = a + b + Point(10, 20);
    std::cout << "a + b + (10,20) = " << d << '\\n';

    // 测试 +=
    a += b;
    std::cout << "a += b 后 a = " << a << '\\n';

    return 0;
    }

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 深入理解C++ 重载 <四> 重载加号运算符
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!