首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【C++重载操作符与转换】算数操作符和关系操作符

【C++重载操作符与转换】算数操作符和关系操作符

作者头像
byte轻骑兵
发布2026-01-21 17:03:26
发布2026-01-21 17:03:26
990
举报

在C++中,操作符重载是一项强大的特性,它允许开发者为自定义类型(如类或结构体)重新定义内置操作符(如+-==等)的行为。这种机制使得自定义类型能够像内置类型一样,通过操作符进行直观的操作。本文将深入探讨算数操作符和关系操作符的重载,结合代码示例和关键知识点,全面掌握这一重要特性。

一、操作符重载的核心价值

1.1 为什么要重载算术与关系操作符

在面向对象编程中,操作符重载赋予自定义类型与内置类型一致的操作体验。对于数学相关类型(如复数、矩阵、几何向量),合理的操作符重载可以:

  • 提升代码可读性
  • 增强类型安全性
  • 实现数学表达式自然表达
代码语言:javascript
复制
// 未重载操作符
Matrix result = matrix1.add(matrix2.multiply(matrix3));

// 重载操作符后
Matrix result = matrix1 + matrix2 * matrix3;

1.2 操作符重载基本原则

原则

说明

示例验证

语义一致性

操作符行为符合直觉

a + b 应执行加法而非其他操作

完备性

相关操作符组应完整重载

重载==必须同时重载!=

效率优化

避免不必要的临时对象创建

使用复合赋值操作符优化运算

1.3 操作符重载的分类

分类

操作符示例

设计建议

算术操作符

+, -, *, /

通常定义为非成员函数,不修改操作数状态,返回新对象。

关系操作符

==, !=, <, >, <=, >=

通常定义为非成员函数,用于比较对象,支持STL容器(如std::sort)的排序需求。

赋值操作符

=

必须定义为成员函数,返回*this的引用,支持链式赋值。

复合赋值操作符

+=, -=, *=, /=

若类支持算术操作符,建议同时定义,提升代码可读性。

自增/自减操作符

++, --

通常定义为成员函数,区分前缀(返回引用)和后缀(返回旧值)形式。

二、算数操作符重载

2.1 基本概念

算数操作符包括 +-*/% 等,用于执行基本的数学运算。在 C++ 中,我们可以为自定义类重载这些操作符,使得它们能够对类对象进行相应的运算。

2.2 重载加法操作符 +

下面以一个简单的 Complex 类(复数类)为例,展示如何重载加法操作符 +

代码语言:javascript
复制
#include <iostream>

class Complex {
private:
    double real;
    double imag;
public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}

    // 重载加法操作符
    Complex operator+(const Complex& other) const {
        return Complex(real + other.real, imag + other.imag);
    }

    void display() const {
        std::cout << real << " + " << imag << "i" << std::endl;
    }
};

int main() {
    Complex c1(1, 2);
    Complex c2(3, 4);
    Complex c3 = c1 + c2;

    std::cout << "c1: ";
    c1.display();
    std::cout << "c2: ";
    c2.display();
    std::cout << "c1 + c2: ";
    c3.display();

    return 0;
}

定义了一个 Complex 类,并重载了加法操作符 +。重载函数 operator+ 接受一个 const Complex& 类型的参数,表示另一个复数对象,返回一个新的 Complex 对象,其实部和虚部分别是两个复数对象实部和虚部的和。

2.3 重载减法、乘法和除法操作符

类似地,我们可以重载减法、乘法和除法操作符。以下是完整的 Complex 类代码,包含了所有这些操作符的重载:

代码语言:javascript
复制
#include <iostream>

class Complex {
private:
    double real;
    double imag;
public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}

    // 重载加法操作符
    Complex operator+(const Complex& other) const {
        return Complex(real + other.real, imag + other.imag);
    }

    // 重载减法操作符
    Complex operator-(const Complex& other) const {
        return Complex(real - other.real, imag - other.imag);
    }

    // 重载乘法操作符
    Complex operator*(const Complex& other) const {
        double newReal = real * other.real - imag * other.imag;
        double newImag = real * other.imag + imag * other.real;
        return Complex(newReal, newImag);
    }

    // 重载除法操作符
    Complex operator/(const Complex& other) const {
        double denominator = other.real * other.real + other.imag * other.imag;
        double newReal = (real * other.real + imag * other.imag) / denominator;
        double newImag = (imag * other.real - real * other.imag) / denominator;
        return Complex(newReal, newImag);
    }

    void display() const {
        std::cout << real << " + " << imag << "i" << std::endl;
    }
};

int main() {
    Complex c1(1, 2);
    Complex c2(3, 4);

    Complex sum = c1 + c2;
    Complex diff = c1 - c2;
    Complex prod = c1 * c2;
    Complex quot = c1 / c2;

    std::cout << "c1: ";
    c1.display();
    std::cout << "c2: ";
    c2.display();

    std::cout << "c1 + c2: ";
    sum.display();
    std::cout << "c1 - c2: ";
    diff.display();
    std::cout << "c1 * c2: ";
    prod.display();
    std::cout << "c1 / c2: ";
    quot.display();

    return 0;
}

2.4 重载复合赋值操作符

复合赋值操作符如 +=-=*=/= 等也可以被重载。以下是 Complex 类中重载 += 操作符的示例:

代码语言:javascript
复制
#include <iostream>

class Complex {
private:
    double real;
    double imag;
public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}

    // 重载 += 操作符
    Complex& operator+=(const Complex& other) {
        real += other.real;
        imag += other.imag;
        return *this;
    }

    void display() const {
        std::cout << real << " + " << imag << "i" << std::endl;
    }
};

int main() {
    Complex c1(1, 2);
    Complex c2(3, 4);

    c1 += c2;

    std::cout << "c1 after c1 += c2: ";
    c1.display();

    return 0;
}

operator+= 函数返回 *this 的引用,这样可以支持链式调用,例如 c1 += c2 += c3;

三、关系操作符重载

3.1 基本概念

关系操作符包括 ==!=<><=>= 等,用于比较两个对象的大小或相等性。通过重载这些操作符,我们可以自定义类对象之间的比较规则。

3.2 重载相等操作符 ==

以下是一个 Point 类,用于表示二维平面上的点,并重载了相等操作符 ==

代码语言:javascript
复制
#include <iostream>

class Point {
private:
    int x;
    int y;
public:
    Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}

    // 重载相等操作符
    bool operator==(const Point& other) const {
        return (x == other.x) && (y == other.y);
    }
};

int main() {
    Point p1(1, 2);
    Point p2(1, 2);
    Point p3(3, 4);

    if (p1 == p2) {
        std::cout << "p1 and p2 are equal." << std::endl;
    } else {
        std::cout << "p1 and p2 are not equal." << std::endl;
    }

    if (p1 == p3) {
        std::cout << "p1 and p3 are equal." << std::endl;
    } else {
        std::cout << "p1 and p3 are not equal." << std::endl;
    }

    return 0;
}

operator== 函数接受一个 const Point& 类型的参数,表示另一个点对象,返回一个布尔值,表示两个点是否相等。

3.3 重载其他关系操作符

类似地,我们可以重载其他关系操作符。以下是 Point 类中重载 < 操作符的示例:

代码语言:javascript
复制
#include <iostream>

class Point {
private:
    int x;
    int y;
public:
    Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}

    // 重载 < 操作符
    bool operator<(const Point& other) const {
        if (x < other.x) {
            return true;
        } else if (x == other.x) {
            return y < other.y;
        }
        return false;
    }
};

int main() {
    Point p1(1, 2);
    Point p2(3, 4);
    Point p3(1, 3);

    if (p1 < p2) {
        std::cout << "p1 < p2" << std::endl;
    } else {
        std::cout << "p1 >= p2" << std::endl;
    }

    if (p1 < p3) {
        std::cout << "p1 < p3" << std::endl;
    } else {
        std::cout << "p1 >= p3" << std::endl;
    }

    return 0;
}

operator< 函数定义了一种比较规则:先比较 x 坐标,如果 x 坐标相等,则比较 y 坐标。

四、操作符重载的注意事项

4.1 操作符重载的限制

  • 只能重载已有的操作符,不能创建新的操作符。
  • 不能改变操作符的优先级和结合性。
  • 部分操作符(如 ::..*?: 等)不能被重载。

4.2 成员函数和非成员函数重载

操作符重载可以作为类的成员函数或非成员函数实现。一般来说,赋值操作符 =、下标操作符 []、函数调用操作符 () 等通常作为成员函数重载,而二元操作符(如 +-*/ 等)可以作为成员函数或非成员函数重载。

4.3 保持操作符的语义一致性

在重载操作符时,应尽量保持操作符的语义与内置类型的语义一致,避免造成混淆。例如,重载 + 操作符应该实现加法的语义,而不是减法。

五、总结

通过操作符重载,我们可以为自定义类对象赋予与内置类型相似的操作能力,从而提高代码的可读性和可维护性。在重载算数操作符和关系操作符时,需要注意操作符的语义一致性、重载的限制以及成员函数和非成员函数的选择。希望本文能帮助你更好地理解和掌握 C++ 中操作符重载的相关知识。

六、代码示例总结

6.1 复数类 Complex 完整代码

代码语言:javascript
复制
#include <iostream>

class Complex {
private:
    double real;
    double imag;
public:
    Complex(double r = 0, double i = 0) : real(r), imag(i) {}

    // 重载加法操作符
    Complex operator+(const Complex& other) const {
        return Complex(real + other.real, imag + other.imag);
    }

    // 重载减法操作符
    Complex operator-(const Complex& other) const {
        return Complex(real - other.real, imag - other.imag);
    }

    // 重载乘法操作符
    Complex operator*(const Complex& other) const {
        double newReal = real * other.real - imag * other.imag;
        double newImag = real * other.imag + imag * other.real;
        return Complex(newReal, newImag);
    }

    // 重载除法操作符
    Complex operator/(const Complex& other) const {
        double denominator = other.real * other.real + other.imag * other.imag;
        double newReal = (real * other.real + imag * other.imag) / denominator;
        double newImag = (imag * other.real - real * other.imag) / denominator;
        return Complex(newReal, newImag);
    }

    // 重载 += 操作符
    Complex& operator+=(const Complex& other) {
        real += other.real;
        imag += other.imag;
        return *this;
    }

    void display() const {
        std::cout << real << " + " << imag << "i" << std::endl;
    }
};

int main() {
    Complex c1(1, 2);
    Complex c2(3, 4);

    Complex sum = c1 + c2;
    Complex diff = c1 - c2;
    Complex prod = c1 * c2;
    Complex quot = c1 / c2;

    std::cout << "c1: ";
    c1.display();
    std::cout << "c2: ";
    c2.display();

    std::cout << "c1 + c2: ";
    sum.display();
    std::cout << "c1 - c2: ";
    diff.display();
    std::cout << "c1 * c2: ";
    prod.display();
    std::cout << "c1 / c2: ";
    quot.display();

    c1 += c2;
    std::cout << "c1 after c1 += c2: ";
    c1.display();

    return 0;
}

6.2 点类 Point 完整代码

代码语言:javascript
复制
#include <iostream>

class Point {
private:
    int x;
    int y;
public:
    Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}

    // 重载相等操作符
    bool operator==(const Point& other) const {
        return (x == other.x) && (y == other.y);
    }

    // 重载 < 操作符
    bool operator<(const Point& other) const {
        if (x < other.x) {
            return true;
        } else if (x == other.x) {
            return y < other.y;
        }
        return false;
    }
};

int main() {
    Point p1(1, 2);
    Point p2(1, 2);
    Point p3(3, 4);
    Point p4(1, 3);

    if (p1 == p2) {
        std::cout << "p1 and p2 are equal." << std::endl;
    } else {
        std::cout << "p1 and p2 are not equal." << std::endl;
    }

    if (p1 == p3) {
        std::cout << "p1 and p3 are equal." << std::endl;
    } else {
        std::cout << "p1 and p3 are not equal." << std::endl;
    }

    if (p1 < p3) {
        std::cout << "p1 < p3" << std::endl;
    } else {
        std::cout << "p1 >= p3" << std::endl;
    }

    if (p1 < p4) {
        std::cout << "p1 < p4" << std::endl;
    } else {
        std::cout << "p1 >= p4" << std::endl;
    }

    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-01-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、操作符重载的核心价值
    • 1.1 为什么要重载算术与关系操作符
    • 1.2 操作符重载基本原则
    • 1.3 操作符重载的分类
  • 二、算数操作符重载
    • 2.1 基本概念
    • 2.2 重载加法操作符 +
    • 2.3 重载减法、乘法和除法操作符
    • 2.4 重载复合赋值操作符
  • 三、关系操作符重载
    • 3.1 基本概念
    • 3.2 重载相等操作符 ==
    • 3.3 重载其他关系操作符
  • 四、操作符重载的注意事项
    • 4.1 操作符重载的限制
    • 4.2 成员函数和非成员函数重载
    • 4.3 保持操作符的语义一致性
  • 五、总结
  • 六、代码示例总结
    • 6.1 复数类 Complex 完整代码
    • 6.2 点类 Point 完整代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档