## 一.运算符重载
1. 本质上也是函数的重载。因此可以当做函数使用。
2. 定义运算符重载函数
+ `返回类型perator 运算符(形参表)`
3. 运算符重载方式
+ **成员函数** 运算符第一个操作数必须为对象自身( **不可以经过类型转换得到** ),其余操作数为形参表中的参数。
+ **友元或普通函数** 运算符重载函数不是成员函数。运算符所有操作数为形参表中的参数。如果需要访问类的非公有成员,应当把该函数声明为 **友元** 。如果第一个操作数为对象自身,则调用时,第一个操作数可以通过类型转换得到得到该类。
+ 如果运算符第一个操作数不是对象自身,则不能重载为 **成员函数** 。
>[warning] VC++6.0 将运算符重载函数声明为友元会出现无法访问非公有成员的BUG,详情见 *面向对象程序设计.类和对象.友元* 。
```c++
#include <iostream>
using namespace std;
class Complex
{
private:
double real_;
double imaginary_;
public:
Complex() : real_(0), imaginary_(0) {}
Complex(double real) : real_(real), imaginary_(0) {}
Complex(double real, double imaginary) : real_(real), imaginary_(imaginary) {}
double get_real() const
{
return this->real_;
}
double get_imaginary() const
{
return this->imaginary_;
}
Complex &set_real(double new_val)
{
this->real_ = new_val;
return *this;
}
Complex &set_imaginary(double new_val)
{
this->imaginary_ = new_val;
return *this;
}
//类内重载示例:重载加法运算符,第一个操作数为对象自身,第二个参数为 another
Complex operator+(const Complex& another) const
{
return Complex(this->real_ + another.real_,this->imaginary_ + another.imaginary_);
}
};
//类外重载示例:重载插入运算符,第一个参数为输出流,第二个参数为 c
ostream& operator<<(ostream& os,const Complex& c)
{
return os<<'('<<c.get_real()<<','<< c.get_imaginary()<<')';
}
int main()
{
Complex c1(5,6),c2(7,8),c3;
c3=c1+c2;//调用 c1.operator+(const Complex& another)
cout<<c3;//调用 ostream& operator<<(ostream& os,const Complex& c)
return 0;
}
```
>[test]
>(12,14)
## 二.运算符重载规则
1. 只能拓充现有运算符的功能,不能定义新的运算符,也不能改变运算符的目数、结合性、优先级等其他属性。除了重载函数调用运算符外,不可在运算符重载函数中添加默认参数。需要注意的是,运算符的重载有可能会改变运算符的求值顺序。
2. 重载的运算符至少有一个操作数为类类型。防止用户修改内置类型数据的运算性质。
3. 应当保证重载运算符的功能与运算符原有的功能类似。
4. 不可重载的运算符:
+ `::(域)` `.(成员访问)` `.*(成员指针访问)` `?:(条件)` `sizeof()(取大小)` `typeid()(获取类型信息)`
5. 只能 **重载为成员函数** 的运算符:
+ `a=b(赋值)` `a(b)(函数调用)` `a[b] (下标访问)` `a-> (成员指针访问)`
- 阅读说明
- 1.1 概述
- C++基础
- 1.2 变量与常量
- 1.2.1 变量
- 1.2.2 字面值常量
- 字符型常量
- 数值型常量
- 1.2.3 cv限定符
- 1.3 作用域
- 1.3.1 标识符
- 1.3.2 *命名空间
- 1.3.3 作用域
- 1.3.4 可见性
- 1.4 数据类型
- 1.4.1 概述
- 1.4.2 处理类型
- 类型别名
- * auto说明符
- * decltype说明符
- 1.4.3 数组
- 1.4.4 指针
- 1.4.5 引用
- 1.5 表达式
- 1.5.1 概述
- 1.5.2 值的类别
- 1.5.3 *初始化
- 1.5.4 运算符
- 算术运算符
- 逻辑和关系运算符
- 赋值运算符
- 递增递减运算符
- 成员访问运算符
- 位运算符
- 其他运算符
- 1.5.5 *常量表达式
- 1.5.6 类型转换
- 第2章 面向过程编程
- 2.1 流程语句
- 2.1.1 条件语句
- 2.1.2 循环语句
- 2.1.3 跳转语句
- 2.1.4 *异常处理
- 2.2 函数
- 2.2.1 概述
- 2.2.2 函数参数
- 2.2.3 内置函数
- 2.2.4 函数重载
- 2.2.5 * 匿名函数
- 2.3 存储和生命期
- 2.3.1 生命周期与存储区域
- 2.3.2 动态内存
- 2.4 *预处理命令
- 第3章 面向对象编程
- 3.1 概述
- 3.2 类和对象
- 3.3 成员
- 3.3.1 访问限制
- 3.3.2 常成员
- 3.3.3 静态成员
- 3.3.4 成员指针
- 3.3.5 this指针
- 3.4 特殊的成员函数
- 3.4.1 概述
- 3.4.2 构造函数
- 3.4.3 析构函数
- 3.4.4 拷贝语义
- 3.4.5 * 移动语义
- 3.5 友元
- 3.6 运算符重载与类型转换
- 3.6.1 概述
- 3.6.2 重载方法
- 3.6.3 类型转换
- 3.7 继承与多态性
- 3.7.1 概述
- 3.7.2 派生类
- 3.7.3 子类型
- 3.7.4 虚基类
- 3.7.5 虚函数
- 3.7.6 抽象类
- 3.8 模板与泛型
- 3.8.1 概述
- 3.8.2 模板类型
- 3.8.3 *模板参数
- 3.8.4 *模板编译
- 3.8.5 *模板推断
- 3.8.6 *实例化与特例化
- 第4章 C++标准库
- 4.1 概述
- 4.2 输入输出流
- 4.2.1 概述
- 4.2.2 *流的状态
- 4.2.3 *常用流
- 4.2.4 *格式化I/O
- 4.2.5 *低级I/O
- 4.2.6 *随机访问
- 4.3 *C输入输出
- 4.3.1 *字符输入输出
- 4.3.2 *格式化输入输出
- 4.4 * 容器
- 4.4.1 * 概述
- 4.4.2 * 基本操作
- 4.4.3 * 顺序容器
- 4.4.4 * 迭代器
- 4.4.5 * 容器适配器
- 4.5 * 泛型算法
- 4.6 * 内存管理
- 4.6.1 * 自动指针
- 4.7 * 其他设施