亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> C语言

C++ 运算符重载完全指南:实战示例与最佳实践

C++ 运算符重载完全指南

本教程通过丰富示例,系统讲解 C++ 运算符重载的语法、一元/二元运算符重载技巧及工程实践注意事项。

在 C++ 中,我们可以改变运算符对用户自定义类型(如类对象、结构体)的行为,这被称为运算符重载。例如,

假设我们从 Complex 类创建了三个对象 c1、c2 和 result,用于表示复数。

通过运算符重载,我们可以重新定义 + 运算符,使其直接支持复数相加:

result = c1 + c2;

而不必调用类似 result = c1.addNumbers(c2); 这样的成员函数。这让代码更直观、易读。

注意: 运算符重载不能用于基本数据类型(如 int、float、char 等)。


运算符重载语法

重载运算符需定义一个特殊的 operator 函数,置于希望重载运算符的类/结构体内部:

class ClassName {
    // ...
public:
    ReturnType operator Symbol(Arguments) {
        // 实现
    }
    // ...
};

其中:


一元运算符重载

一元运算符仅作用于单个操作数。自增 ++ 和自减 -- 是典型的一元运算符。


示例 1:前缀 ++ 运算符重载

// 重载前缀 ++
#include <iostream>
using namespace std;

class Count {
private:
    int value;
public:
    // 构造函数初始化为 5
    Count() : value(5) {}
    // 重载前缀 ++
    void operator ++ () {
        ++value;
    }
    void display() {
        cout << "Count: " << value << endl;
    }
};

int main() {
    Count count1;
    // 调用 void operator ++ ()
    ++count1;
    count1.display();
    return 0;
}

输出

Count: 6

使用 ++count1 时,会调用 void operator ++ (),将对象 count1 的 value 增加 1。

注意: 重载运算符时,我们可以让其表现为任意行为(如让 ++ 增加 100),但这会让代码极难理解。程序员应确保重载行为符合直觉、保持一致性。


上例仅支持前缀形式。要支持后缀 ++,需使用以下语法:

void operator ++ (int) { // 代码 }

参数列表中的 int 仅为标识后缀形式的约定标记,并非真实参数。


示例 2:同时重载前缀与后缀 ++

// 同时重载前缀和后缀 ++
#include <iostream>
using namespace std;

class Count {
private:
    int value;
public:
    Count() : value(5) {}
    // 前缀 ++
    void operator ++ () {
        ++value;
    }
    // 后缀 ++
    void operator ++ (int) {
        value++;
    }
    void display() {
        cout << "Count: " << value << endl;
    }
};

int main() {
    Count count1;
    // 调用后缀版本
    count1++;
    count1.display();
    // 调用前缀版本
    ++count1;
    count1.display();
    return 0;
}

输出

Count: 6
Count: 7

示例 2 同时支持前缀和后缀,但无法支持如下用法:

Count count1, result;
// 错误:返回类型为 void
result = ++count1;

解决方法是让运算符函数返回 Count 类型:

// 前缀返回 Count
Count operator ++ () { /* ... */ }
// 后缀返回 Count
Count operator ++ (int) { /* ... */ }

示例 3:运算符函数返回值(++ 运算符)

#include <iostream>
using namespace std;

class Count {
private:
    int value;
public:
    Count() : value(5) {}
    // 前缀 ++ 返回新对象
    Count operator ++ () {
        Count temp;
        temp.value = ++value;  // 先自增,再赋值给 temp
        return temp;
    }
    // 后缀 ++ 返回旧值副本
    Count operator ++ (int) {
        Count temp;
        temp.value = value++;  // 先赋值,再自增
        return temp;
    }
    void display() {
        cout << "Count: " << value << endl;
    }
};

int main() {
    Count count1, result;
    // 前缀:result 获取自增后的值
    result = ++count1;
    result.display();  // 6
    // 后缀:result 获取自增前的值
    result = count1++;
    result.display();  // 6
    return 0;
}

输出

Count: 6
Count: 6

前缀版本中 temp.value = ++value; 先增加 value(属于调用对象 count1),再赋值给临时对象 temp。后缀版本则先用旧值初始化 temp,再增加 value。


二元运算符重载

二元运算符作用于两个操作数,如 result = num + 9; 中的 +。

为用户自定义类型重载二元运算符时:

obj3 = obj1 + obj2;

运算符函数由 obj1 调用,obj2 作为参数传入。


示例 4:二元运算符 + 重载(复数相加)

// 重载二元运算符 + 实现复数加法
#include <iostream>
using namespace std;

class Complex {
private:
    float real;   // 实部
    float imag;   // 虚部
public:
    Complex() : real(0), imag(0) {}
    void input() {
        cout << "Enter real and imaginary parts respectively: ";
        cin >> real >> imag;
    }
    // 重载 + 运算符
    Complex operator + (const Complex& obj) {
        Complex temp;
        temp.real = real + obj.real;
        temp.imag = imag + obj.imag;
        return temp;
    }
    void output() {
        if (imag < 0)
            cout << "Output Complex number: " << real << imag << "i";
        else
            cout << "Output Complex number: " << real << "+" << imag << "i";
    }
};

int main() {
    Complex complex1, complex2, result;
    cout << "Enter first complex number:\n";
    complex1.input();
    cout << "Enter second complex number:\n";
    complex2.input();
    // complex1 调用 operator+,complex2 作为参数
    result = complex1 + complex2;
    result.output();
    return 0;
}

输出

Enter first complex number:
Enter real and imaginary parts respectively: 9 5
Enter second complex number:
Enter real and imaginary parts respectively: 7 6
Output Complex number: 16+11i
C++ 运算符重载完全指南:实战示例与最佳实践

运算符函数签名为:

Complex operator + (const Complex& obj)

也可写为 Complex operator + (Complex obj),但推荐使用 const Complex&:


C++ 运算符重载注意事项

  1. = 和 & 默认已重载。同类对象赋值可直接用 =,无需自定义。
  2. 运算符重载不能改变运算符的优先级和结合性。若需改变求值顺序,应使用括号。
  3. 有 4 个运算符无法重载:
    1. ::(作用域解析)
    2. .(成员访问)
    3. .*(成员指针访问)
    4. ?:(三元条件运算符)

延伸阅读:

C语言

  1. C#运算符——C#运算符全面指南
  2. C# 三元运算符:条件表达式简明指南
  3. 掌握 C# 方法重载:核心概念、实战示例与最佳实践
  4. 掌握 C# 构造函数重载:灵活创建对象的多种姿势
  5. 掌握 C++ 运算符:六大类型全解析与实战示例
  6. C++ 注释最佳实践:编写可读、可维护代码的注释艺术
  7. C++ 类模板实战指南:编写灵活的类型无关代码
  8. C++ 运算符全解析:类型、示例与示例程序
  9. C++ 运算符重载实战指南:语法、方法、限制与代码示例
  10. C++编程语言:核心特性全景解析
  11. C++常量与字面量完全手册:类型、语法与最佳实践
  12. 精通 Python 运算符重载:实战指南