前言
✨欢迎来到小K的C++专栏,本节将为大家带来C++运算符重载 — 意义 | 限制 | 方法 | 规则 | 特殊运算符重载 | 应用场景 的分享✨
目录
- 前言
- 一、运算符重载的意义
- 二、运算符重载限制
- 三、运算符重载规则
- 四、运算符重载方法
- 五、C++特殊运算符重载
- 1、++和--运算符的重载
- 2、C++流对象重载
- 3、C++文本重载
- 4、C++operator实现隐式转换
- 六、运算符重载的应用场景
- 1、迭代器实现
- 2、函数包装器
- 3、智能指针
- 总结
运算符重载,就是赋予运算符新的含义。它是重载系统内部运算符的函数,是实现类静态多态性的方式之一。它本质上是函数重载。
实际上,我们已经在不知不觉之中使用了运算符重载。列如:我们习惯使用的对整数,浮点数运用+、-、*、/,起始计算机对整数和浮点数的操作过程是不一样的,但由于C++已经对运算符进行了重载,所以才能都适用。
又如<<本来是左移运算符,但在输出操作中,与cout搭配,当作输出流运算符了
一、运算符重载的意义
我们平常常见的算术运算符、逻辑运算符等运算符都是系统库函数里面已经存在的,所以运算符可以直接用于我们常用的数据类型。然而对于我们自定义的类实例化的对象,系统没有与之相关的运算符可以操作,但是为了使我们编写程序时更加便捷,C++提供了一种方式——运算符重载,来满足我们对于类对象进行的操作。
也就是说运算符重载是为了解决类对象之间的运算的,让编译器在遇到对象运算时能按我们要求的进行运算,这就是运算符重载的意义。
二、运算符重载限制
C++中绝大部分的运算符允许重载,少部分不允许重载,详细描述如下
可以重载的运算符
- 算术运算符:+ - * / %
- 自增、自减运算符:++ –
- 位运算符:| & ~ ^ << >>
- 逻辑运算符:|| && !
- 关系运算符:== != < > <= >=
- 赋值运算符:= += -= /= %= &= |= ^= <<= >>=
- 单目运算符:+ - * &
- 动态内存分配:new delete new[] delete[]
- 其他运算符:() -> , []
不能重载的运算符
- . 成员访问运算符
- :: 域运算符
- .* ->* 成员指针访问运算符
- szieof 长度运算符
- ?: 条件运算符
三、运算符重载规则
- 重载运算符函数可以对运算符作出新的解释﹐但原有基本语义不变:
- 不改变运算符的优先级
- 不改变运算符的结合性
- 不改变运算符所需要的操作数
- 不能创建新的运算符
- 语法:
- 一个运算符被重载后,原有意义没有失去,只是定义了相对一特定类的一个新运算符。
- 函数返回值:当前运算符运算结束后产物类型,
int a,int b,a+b
返回int类型- 函数名:
operator
和运算符组成函数名- 函数参数
- 运算符重载函数是类中成员函数:函数参数等于操作数-1
- 运算符重载函数是友元函数:函数参数等于操作数
- 函数体:写运算符的实际想要的运算
- c++类中存在一个赋值的重载函数(默认)
四、运算符重载方法
两种重载方法
重载为成员函数或全局(友元)函数
两种形式的选择时机:
- 左操作数(或者只有左操作数并且)是本类的对象时,可选用成员函数形式。
- 左操作数不是本类的对象,必须采用非成员函数的形式,一般是友元函数。
- 一般单目运算符最好被重载为成员函数;双目运算符重载为友元函数。
- 有些运算符不能重载为友元函数,它们是:=,(),[]和->。
- 具有可交换性的双目运算符最好两种形式都有(成员函数时适用左操作数为本类对象,友元函数时适用左操作数为其他类的对象)。
五、C++特殊运算符重载
1. .= () -> [] 只能重载为类成员函数
2. 运算符重载必须存在至少一个自定义类型才能重载
3. . .* ?: :: 不能被重载
4. C++只允许重载已有运算符,不能无中生有
5. 习惯行为:单目运算符采用类的成员函数重载,双目运算符采用友元重载
1、++和–运算符的重载
对于++和–重载,通过增加无用参数(int)标识为后置运算,下面是一个代码示例和示例结果
2、C++流对象重载
cout
本质是一个类的对象:ostream
,cin本质也是一个类的对象:istream
- 流重载必须要用友元方式重载
- 流重载尽量使用引用类型
3、C++文本重载
- 所谓文本重载,就是重载后缀,固定写法
- 函数参数:
unsigned long long
(一定是)- 函数名:
operator""
要重载的后缀 —— 一般重载后缀采用下划线系列- 一个运算符或者一个后缀只能重载被重载一次
本例中重载时间中的时分秒,用起来非常简便
4、C++operator实现隐式转换
- 所谓隐式转换就是可以让对象直接赋值给普通对象——便捷获取数据成员的接口
- 模板
六、运算符重载的应用场景
1、迭代器实现
- 让对象模拟指针的行为
- 模板
2、函数包装器
- 把函数指针包装成一个对象
3、智能指针
- 可以实现内存的自动申请与释放
总结
通过运算符重载,可以使自定义类型的操作更加直观和方便。但在进行运算符重载时,需要遵守一定的规则和限制,以确保代码的正确性和可维护性。