C++中加号重载运算符的具体使用

 更新时间:2026年02月03日 09:28:48   作者:挖矿大亨  
本文主要介绍了C++中加号重载运算符的具体使用,包括成员函数重载和全局函数(友元)重载两种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在 C++ 中,加号(+)运算符重载 是最常用的运算符重载场景之一,用于让自定义类型(如类、结构体)支持 + 操作(例如复数相加、自定义数值类型相加、字符串拼接等)。+ 是双目运算符(需要两个操作数),重载方式分为「成员函数重载」和「全局函数(友元)重载」,两种方式各有适用场景。

一、核心规则

  • 运算符重载后,优先级、结合性、操作数个数与原生 + 完全一致;
    重载的 + 应遵循 “值语义”:通常返回新对象(而非修改原对象),符合用户对 + 的直觉(如 a + b 不改变 a 和 b,返回相加结果);
    可重载为成员函数(左操作数是当前类对象)或全局函数 / 友元(支持左操作数为其他类型,如 int + 自定义类)。

二、两种重载方式详解

方式 1:成员函数重载 + 运算符

语法:在类内部声明 / 定义成员函数,格式为:

  • 返回值类型 operator+(const 类名& 右操作数) const;
  • onst 修饰成员函数:保证不修改当前对象(左操作数),符合 + 不改变原对象的语义;
  • 右操作数用 const&:避免拷贝,且保证能接收常量对象;

返回值:返回新构造的对象(相加结果)。

示例:复数类相加(成员函数重载)

#include <iostream>
using namespace std;

// 复数类:实部 + 虚部i
class Complex {
private:
    double real; // 实部
    double imag; // 虚部
public:
    // 构造函数
    Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}

    // 成员函数重载 + 运算符(左操作数是this,右操作数是c)
    Complex operator+(const Complex& c) const {
        // 不修改this和c,返回新的复数对象
        return Complex(real + c.real, imag + c.imag);
    }

    // 打印函数
    void print() const {
        cout << real << " + " << imag << "i" << endl;
    }
};

int main() {
    Complex c1(1.5, 2.5), c2(3.5, 4.5);
    Complex c3 = c1 + c2; // 等价于 c1.operator+(c2)
    c1.print(); // 1.5 + 2.5i(原对象未修改)
    c2.print(); // 3.5 + 4.5i(原对象未修改)
    c3.print(); // 5 + 7i(相加结果)
    return 0;
}

方式 2:全局函数(友元)重载 + 运算符

当需要支持「左操作数不是当前类对象」的场景(如 int + Complex),成员函数重载无法实现(因为成员函数的左操作数必须是当前类对象),此时需用全局函数重载,若需要访问类的私有成员,可声明为友元。
语法:

// 类内声明友元(如需访问私有成员)
friend 返回值类型 operator+(const 类名& 左操作数, const 类名& 右操作数);

// 全局定义
返回值类型 operator+(const 类名& 左操作数, const 类名& 右操作数) {
    // 实现相加逻辑
}

示例 1:支持 Complex + Complex 和 int + Complex

#include <iostream>
using namespace std;

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

    // 声明友元:支持 Complex + Complex
    friend Complex operator+(const Complex& c1, const Complex& c2);
    // 声明友元:支持 int + Complex
    friend Complex operator+(int num, const Complex& c);
    // 声明友元:支持 Complex + int(可选,对称设计)
    friend Complex operator+(const Complex& c, int num);

    void print() const {
        cout << real << " + " << imag << "i" << endl;
    }
};

// 全局定义:Complex + Complex
Complex operator+(const Complex& c1, const Complex& c2) {
    return Complex(c1.real + c2.real, c1.imag + c2.imag);
}

// 全局定义:int + Complex
Complex operator+(int num, const Complex& c) {
    return Complex(num + c.real, c.imag);
}

// 全局定义:Complex + int
Complex operator+(const Complex& c, int num) {
    return Complex(c.real + num, c.imag);
}

int main() {
    Complex c1(1.5, 2.5);
    Complex c2 = 10 + c1; // int + Complex
    Complex c3 = c1 + 20; // Complex + int
    Complex c4 = c1 + c2; // Complex + Complex

    c2.print(); // 11.5 + 2.5i
    c3.print(); // 21.5 + 2.5i
    c4.print(); // 13 + 5i
    return 0;
}

三、特殊场景:重载 += 与 + 的配合

+= 是修改自身的运算符(左操作数被修改),通常先重载 +=,再基于 += 重载 +,减少代码冗余

#include <iostream>
using namespace std;

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

    // 重载 +=(成员函数,修改自身)
    Complex& operator+=(const Complex& c) {
        real += c.real;
        imag += c.imag;
        return *this; // 返回自身,支持链式操作(如 c1 += c2 += c3)
    }

    // 基于 += 重载 +(成员函数)
    Complex operator+(const Complex& c) const {
        Complex temp = *this; // 拷贝当前对象
        temp += c; // 复用 += 逻辑
        return temp;
    }

    void print() const {
        cout << real << " + " << imag << "i" << endl;
    }
};

int main() {
    Complex c1(1, 2), c2(3, 4);
    c1 += c2; // c1 被修改:4 + 6i
    c1.print();

    Complex c3 = c1 + c2; // c3:7 + 10i
    c3.print();
    return 0;
}

四、常见误区与注意事项

1、返回值类型错误:

+ 运算符应返回新对象(值返回),而非引用(引用会指向临时对象,导致未定义行为);
+= 运算符应返回自身引用(Complex&),支持链式操作。

2、修改原对象:

重载 + 时,切勿修改左 / 右操作数(违反用户直觉),必须保证 a + b 不改变 a 和 b。

3、友元的滥用:

仅当需要访问私有成员时才将全局 + 声明为友元,否则优先用公共接口实现(如通过 getReal()/getImag() 获取成员)。

4、不支持混合类型的对称重载:

若需要 A + B 和 B + A 都生效,需分别重载两个全局函数(如 operator+(A, B) 和 operator+(B, A))。

5、不能重载原生类型的 +:

C++ 不允许重载内置类型(如 int + int)的运算符,只能重载至少包含一个自定义类型的运算符。

五、完整示例:字符串拼接(重载 +)

#include <iostream>
#include <cstring>
using namespace std;

class MyString {
private:
    char* str;
    int len;
public:
    // 构造函数
    MyString(const char* s = "") {
        len = strlen(s);
        str = new char[len + 1];
        strcpy(str, s);
    }

    // 析构函数
    ~MyString() {
        delete[] str;
    }

    // 拷贝构造(避免浅拷贝)
    MyString(const MyString& other) {
        len = other.len;
        str = new char[len + 1];
        strcpy(str, other.str);
    }

    // 重载 +:字符串拼接
    friend MyString operator+(const MyString& s1, const MyString& s2) {
        MyString temp;
        temp.len = s1.len + s2.len;
        delete[] temp.str; // 释放默认构造的空字符串
        temp.str = new char[temp.len + 1];
        strcpy(temp.str, s1.str);
        strcat(temp.str, s2.str);
        return temp;
    }

    // 打印字符串
    void print() const {
        cout << str << endl;
    }
};

int main() {
    MyString s1("Hello"), s2(" World!");
    MyString s3 = s1 + s2;
    s3.print(); // Hello World!
    return 0;
}

总结

1、成员函数重载 +:适用于左操作数是当前类对象的场景,语法简洁,无需友元;
2、全局函数重载 +:适用于混合类型(如 int + 自定义类)或对称重载的场景,需按需声明友元;
3、遵循 “值语义”:+ 返回新对象,+= 返回自身引用,保证行为符合用户直觉;
4、复用逻辑:优先实现 +=,再基于 += 实现 +,减少代码冗余

到此这篇关于C++中加号重载运算符的具体使用的文章就介绍到这了,更多相关C++ 加号重载运算符内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C生万物C语言宏将整数二进制位的奇偶数位交换

    C生万物C语言宏将整数二进制位的奇偶数位交换

    这篇文章主要为大家介绍了C生万物C语言使用宏将整数二进制位的奇偶数位交换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • C/C++语言宏定义使用实例详解

    C/C++语言宏定义使用实例详解

    这篇文章主要介绍了 C/C++语言宏定义使用实例详解的相关资料,需要的朋友可以参考下
    2017-06-06
  • C++ string和wstring相互转换方式

    C++ string和wstring相互转换方式

    这篇文章主要介绍了C++ string和wstring相互转换方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • C语言中储存类别与内存管理的深入理解

    C语言中储存类别与内存管理的深入理解

    这篇文章主要给大家介绍了关于C语言中储存类别与内存管理的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • vscode配置远程开发环境并远程调试运行C++代码的教程

    vscode配置远程开发环境并远程调试运行C++代码的教程

    这篇文章主要介绍了vscode配置远程开发环境并远程调试运行C++代码的教程,本文通过截图实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • 关于vector迭代器失效的几种情况总结

    关于vector迭代器失效的几种情况总结

    下面小编就为大家带来一篇关于vector迭代器失效的几种情况总结。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • MFC中Radio Button的用法详解

    MFC中Radio Button的用法详解

    这篇文章主要介绍了MFC中Radio Button的用法,需要的朋友可以参考下
    2014-07-07
  • Linux网络编程之基于UDP实现可靠的文件传输示例

    Linux网络编程之基于UDP实现可靠的文件传输示例

    这篇文章主要介绍了Linux网络编程之基于UDP实现可靠的文件传输示例,是很实用的技巧,需要的朋友可以参考下
    2014-08-08
  • QT中QStringListModel类的应用介绍

    QT中QStringListModel类的应用介绍

    QStringListModel是最简单的模型类,具备向视图提供字符串数据的能力,本文主要介绍了QT中QStringListModel类的应用介绍,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • OpenCV实现物体的凸包检测的示例代码

    OpenCV实现物体的凸包检测的示例代码

    给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸边形,它是包含点集中所有的点。本文将利用OpenCV实现物体的凸包检测,感兴趣的可以了解一下
    2022-08-08

最新评论