> For the complete documentation index, see [llms.txt](https://dev2ero.gitbook.io/notes-cs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dev2ero.gitbook.io/notes-cs/programming/programing-language/c++/mian-xiang-dui-xiang/zhong-xie-yu-zhong-zai/yun-suan-fu-zhong-zai.md).

# 运算符重载

### 作为成员函数

下面的代码定义了一个复数类，通过运算符重载，可以用`+`号实现复数的加法运算：

```
#include <iostream>

using namespace std;

class complex{
public:
    complex();
    complex(double real, double imag);
public:
    //声明运算符重载
    complex operator+(const complex &A) const;
    void display() const;
private:
    double m_real;  //实部
    double m_imag;  //虚部
};

complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }

//实现运算符重载
complex complex::operator+(const complex &A) const{
    complex B;
    B.m_real = this->m_real + A.m_real;
    B.m_imag = this->m_imag + A.m_imag;
    return B;
}

void complex::display() const{
    cout<<m_real<<" + "<<m_imag<<"i"<<endl;
}

int main(){
    complex c1(4.3, 5.8);
    complex c2(2.4, 3.7);
    complex c3;
    c3 = c1 + c2;
    c3.display();
    return 0;
}
```

运行结果： 6.7 + 9.5i

本例中义了一个复数类 complex，m\_real 表示实部，m\_imag 表示虚部，第 10 行声明了运算符重载，第 21 行进行了实现（定义）。认真观察这两行代码，可以发现运算符重载的形式与函数非常类似。

运算符重载其实就是定义一个函数，在函数体内实现想要的功能，当用到该运算符时，编译器会自动调用这个函数。也就是说，运算符重载是通过函数实现的，它本质上是函数重载。

运算符重载的格式为：

```
返回值类型 operator 运算符名称 (形参表列){
    //TODO:
}
```

`operator`是关键字，专门用于定义重载运算符的函数。我们可以将`operator 运算符名称`这一部分看做函数名，对于上面的代码，函数名就是`operator+`。\
\
运算符重载函数除了函数名有特定的格式，其它地方和普通函数并没有区别。\
\
上面的例子中，我们在 complex 类中重载了运算符`+`，该重载只对 complex 对象有效。当执行`c3 = c1 + c2;`语句时，编译器检测到`+`号左边（`+`号具有左结合性，所以先检测左边）是一个 complex 对象，就会调用成员函数`operator+()`，也就是转换为下面的形式：

```
c3 = c1.operator+(c2);
```

c1 是要调用函数的对象，c2 是函数的实参。

上面的运算符重载还可以有更加简练的定义形式：

```
complex complex::operator+(const complex &A)const{
    return complex(this->m_real + A.m_real, this->m_imag + A.m_imag);
}
```

return 语句中的`complex(this->m_real + A.m_real, this->m_imag + A.m_imag)`会创建一个临时对象，这个对象没有名称，是一个匿名对象。在创建临时对象过程中调用构造函数，return 语句将该临时对象作为函数返回值。

### 作为全局函数

运算符重载函数不仅可以作为类的成员函数，还可以作为全局函数。这相当于不是直接为类本身实现了一个新的方法，而是为某个运算符重载了一个函数（能以新类为参数的函数）。

更改上面的代码，在全局范围内重载`+`，实现复数的加法运算：

```
#include <iostream>

using namespace std;

class complex{
public:
    complex();
    complex(double real, double imag);
public:
    void display() const;
    //声明为友元函数
    friend complex operator+(const complex &A, const complex &B);
private:
    double m_real;
    double m_imag;
};

complex operator+(const complex &A, const complex &B);
complex::complex(): m_real(0.0), m_imag(0.0){ }
complex::complex(double real, double imag): m_real(real), m_imag(imag){ }

void complex::display() const{
    cout<<m_real<<" + "<<m_imag<<"i"<<endl;
}

//在全局范围内重载+
complex operator+(const complex &A, const complex &B){
    complex C;
    C.m_real = A.m_real + B.m_real;
    C.m_imag = A.m_imag + B.m_imag;
    return C;
}

int main(){
    complex c1(4.3, 5.8);
    complex c2(2.4, 3.7);
    complex c3;
    c3 = c1 + c2;
    c3.display();
    return 0;
}
```

运算符重载函数不是 complex 类的成员函数，但是却用到了 complex 类的 private 成员变量，所以必须在 complex 类中将该函数声明为友元函数。\
\
当执行`c3 = c1 + c2;`语句时，编译器检测到`+`号两边都是 complex 对象，就会转换为类似下面的函数调用：

```
c3 = operator+(c1, c2);
```

以上两种方案都说明了，运算符本身和函数的行为并无大异，使用`operator运算符`来获取运算符对应的“函数”。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dev2ero.gitbook.io/notes-cs/programming/programing-language/c++/mian-xiang-dui-xiang/zhong-xie-yu-zhong-zai/yun-suan-fu-zhong-zai.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
