---
sidebar_position: 3
tags: [Language, C++, Operator, Overload]
---

# Operators

## 左/右值运算符

- 左值运算符: 前置 `++`/`--`, `=`/`+=`/`*=`/`&=`/`op=`.
- 右值运算符: 强制类型转换(不可对其运算结果进行取地址), `+`/`*`/`binary`.

## sizeof

```cpp
sizeof 数值
sizeof(数值)
sizeof(类型)

sizeof(printf("abcd")); // 无输出
```

## Overload

| 运算符                      | 重载方式                                |
| :-------------------------- | :-------------------------------------- |
| `sizeof` `.` `.*` `::` `?:` | 不可重载                                |
| `=` `->` `()` `[]`          | (必须有 this 指针)普通函数成员          |
| `new` `delete`              | (不可有 this 指针)静态函数成员 普通函数 |
| 其他运算符                  | 普通函数成员 普通函数                   |

### 原则

- 若运算符为左值运算符, 则重载返回类型为非 const 引用类型
- 若运算符为非左值运算符, 则重载返回类型为普通类型(栈内存)或 const 类型
- 重载为普通函数成员, this 占据第一个参数位置
- 重载不改变运算符的优先级与结合性

### 自增/减运算符

```cpp
A &A::operator++();     ///< 前置++
A A::operator++(int);   ///< 后置++, int 参数只起区分作用
```

### 成员运算符

只能重载为普通函数成员, 只有一个参数(+ this), 返回类型必须为指针/引用类型

```cpp
struct A {
    int a;
};

class B {
    A x;
public:
    A *operator->() {
        return &x;
    }
};

int main(void) {
    B b;
    int i = b->a;               // i = b.x.a
    i = (*b.operator->()).a;    // i = b.x.a
    i = b.operator->()->a;      // i = b.x.a
}
```

### 赋值运算符

- 所有对象都有默认的 = 重载: 浅拷贝赋值运算

### 强制类型转换

- 当定义只有一个参数的构造函数时, 进行运算时会自动发生类型转换(利用右值调用此构造函数, 生成中间变量赋给左值)

```cpp
Complex m;
m + 2 => m + 2.0 => m + Complex(2.0);
```
