C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++ 加号重载运算符

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

作者:挖矿大亨

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

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

一、核心规则

二、两种重载方式详解

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

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

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

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

#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++ 加号重载运算符内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文