C++学习之路—运算符重载(一)概念、方法及规则
(根据《C++程序设计》(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明)
1 什么是运算符重载
先来说下什么是重载吧!所谓重载,就是赋予新的含义。重载包括函数重载和运算符重载。函数重载就是对一个已有的函数赋予新的含义,使之实现新的功能,因此,同一个函数名就可以用来代表不同功能的函数,也就是一名多用。函数重载在以后的博客中会陆续介绍,这个系列先只介绍运算符重载。
运算符也可以重载,实际上,我们已经在不知不觉中使用了运算符重载。例如,大家大家已经习惯于用加法运算符“+”对整数、单精度数和双精度数进行加法,其实,计算机处理整数、单精度数和双精度数加法的操作方法是不同的,由于C++已经对运算符“+”进行了重载,使“+”能适用于int、float、double类型的不同的运算。
现在要讨论的问题是:用户能否根据自己的需要对C++已经提供的运算符进行重载,赋予它们新的含义,使之一名多用。例如,能否用“+”号进行两个复数的相加。在C++中是不能在程序中直接用运算符“+”对复数进行相加运算。用户必须自己设法实现复数相加。
最容易想到的方法是:自己定义一个专门的函数来实现复数相加。例如:
1: class Complex //定义Complex类
2: {
3: public:
4: ...
5: Complex complex_add( Complex& c2 ) ; //声明复数相加函数
6: private:
7: double real ; //实部
8: double imag ; //虚部
9: };
10:
11: Complex Complex :: complex_add( Complex& c2 ) //定义复数相加函数
12: {
13: Complex c ;
14: c.real = real + c2.real ;
15: c.imag = imag + c2.imag ;
16: return c ;
17: }
此方法采用在Complex类中定义complex_add函数,其作用是将两个复数相加,在该函数体中定义一个Complex类对象c作为临时对象。其中的赋值语句相当于
1: c.real = this->real + c2.real ;
2: c.imag = this->imag + c2.imag ;
this是当前对象的指针。
利用上述方法得到的结果是正确的,但调用很不方便。人们自然会想到:能否也和整数的加法运算一样,直接用“+”来实现复数运算,这就需要对“+”进行重载。
2 运算符重载的方法
运算符重载的方法是定义一个重载运算符的函数,使指定的运算符不仅能实现原有的功能,而且还能实现函数中指定的新功能。在使用被重载的运算符时,系统就自动调用该函数,以实现相应的功能。运算符的重载实质上是函数的重载。
运算符重载的一般格式如下:
函数类型 operator 运算符名称(形参表)
{ 对运算符的重载处理 }
在上面的一般格式中,operator是关键字,是专门用于定义重载运算符的函数的,函数名使用operator和运算符组成。
例,对运算符“+”进行重载,使之能用于两个复数相加:
1: class Complex
2: {
3: public:
4: ...
5: Complex operator + ( Complex& c2 ) ; //声明重载运算符 + 的函数
6: private:
7: double real ;
8: double imag ;
9: };
10:
11: Complex Complex :: operator + ( Complex& c2 ) //定义重载运算符 + 的函数
12: {
13: Complex c ;
14: c.real = real + c2.real ;
15: c.imag = imag + c2.imag ;
16: return c ;
17: }
经过这样的声明和定义之后,若c1、c2、c3都是Complex类的对象,在进行两个复数相加时,就可以这样:
1: c3 = c1 + c2 ;
将运算符"+"'重载为类的成员函数后,C++编译系统将程序中的表达式"c3=c2+c1"解释为" c1.operator + ( c2 ) ",表示以c2为实参调用c1的运算符重载函数operator+,进行两个复数相加。
通过以上的比较可以看到,无论是通过自定义complex_add函数,还是重载“+”运算符,两个程序的结构和执行过程基本上是相同的,作用相同,运行结果也相同。那为什么还要进行运算符重载呢?这就要从用户的角度来思考问题,虽然重载运算符所实现的功能完全可以由函数实现,但是使用运算符重载能使用户易于编写、阅读和维护。
注意:运算符被重载后,其原有的功能仍然保留,没有丧失或改变。也就是说同一个运算符可以代表不同的功能,当编译系统需要判别该执行哪一个功能的时候,是根据表达式的上下文决定的,即根据运算符两侧的数据类型来决定的。
总结一下:本来C++提供的运算符只能用于标准类型数据的运算,但C++程序设计的重要基础是类和对象,如果C++的运算符无法用于类和对象,则类和对象的应用将会受到很大的限制。为了解决这个问题,使类和对象有更强的生命力,C++允许重载现用的运算符,使这些简单易用、众所周知的运算符能直接应用于自己定义的类和对象。
3 重载运算符的规则
(1)C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载。
(2)C++允许重载的运算符。
记住不能重载的运算符:
成员访问运算符: .
成员指针运算符:*
作用域运算符: ::
长度运算符:sizeof
条件运算符:?:
(3)重载不能改变运算符运算对象的个数。
如关系运算符“<”“>”等是双目运算符,重载后仍为双目运算符,需要两个参数。有些运算符既可以作为单目运算符,也可以作为双目运算符,这就需要分别重载。
(4)重载不能改变运算符的优先级别。
(5)重载不能改变运算符的结合性。
(6)重载运算符的函数不能有默认的参数。否则就改变了运算符参数的个数,与(3)矛盾。
(7)重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类的对象或类的引用。也就说参数不能全是C++的标准类型,以防止用户修改用于标准类型数据的运算符的性质。
(8)用于类对象的运算符一般必须重载,但有两个例外,运算符“=”和“&”不必用户重载。
(9)应当使重载运算符的功能类似于该运算符作用于标准类型数据时所实现的功能。
C++学习之路—运算符重载(一)概念、方法及规则的更多相关文章
- C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对运算符重载的函数有两种处理方式:(1)把运算符 ...
- C++学习26 运算符重载的概念和语法
所谓重载,就是赋予新的含义.函数重载(Function Overloading)可以让一个函数名有多种功能,在不同情况下进行不同的操作.运算符重载(Operator Overloading)也是一个道 ...
- C++学习笔记之运算符重载
一.运算符重载基本知识 在前面的一篇博文 C++学习笔记之模板(1)——从函数重载到函数模板 中,介绍了函数重载的概念,定义及用法,函数重载(也被称之为函数多态)就是使用户能够定义多个名称相同但特征标 ...
- scala学习手记7 - 运算符重载
从语法上来说scala是没有运算符的.之前的一节里也曾提到过scala的运算符实际上是方法名,如1 + 2实际上就是1.+(2).我们可以将之视为运算符,是因为scala的一个特性:如果方法的参数小于 ...
- 【dart学习】之运算符重载
一,什么是运算符重载(operator overloading) 在软件开发过程中,运算符重载(英语:operator overloading)是多态的一种.运算符重载通常只是一种语法糖,这种语法对语 ...
- Python3学习之路~8.1 socket概念及参数介绍
一 socket介绍 TCP/IP 基于TCP/IP协议栈的网络编程是最基本的网络编程方式,主要是使用各种编程语言,利用操作系统提供的套接字网络编程接口,直接开发各种网络应用程序. socket概念 ...
- osgi实战学习之路:3. osgi分层概念及相互合作demo
源码下载 分层: modual: 主要作用于包级管理与共享代码 lifecycle: 主要作用于执行期间的模块管理与訪问osgi底层框架 service: 主要作用于多模块之间的相互通信 demo: ...
- vb编程学习之路之基础与概念总结
OOP (Object Oriented Programming)面向对象程序设计/面向对象编程 对象是代码和数据的集合,对象的三要素:属性.事件.方法 对象的命令规则:必须以字母或汉字开头,不能以数 ...
- Linux学习之路三:重要概念之Linux系统层次结构
上图来自Unix编程圣经<APUE>英文第二版.如图,处于最中心的是系统内核,负责机器硬件资源管理,进程管理等:shell,函数库(值得记住的是C标准函数库)和某些应用程序均直接构建于内核 ...
随机推荐
- G - 小希的迷宫(并查集)
1今天准备复习三道以前做过的题呢,结果只看了一道,也因为交题的时候没把测试时候为了方便而改的数字改过来而wrong answer,浪费了好长时间,啊啊啊~~ 不过这道题应该是掌握了,嘿嘿…… Desc ...
- Group DataList
一,效果图. 二,源代码. <!DOCTYPE html><html><head> <meta charset="UTF-8"> & ...
- input file 在开发中遇到的问题 类似ajax form表单提交 input file中的文件
最近在做项目的过程中遇到个问题,在这里做个记录防止日后忘记 现今的主流浏览器由于ajax提交form表单无法把文件类型数据提交到后台,供后台处理,可是开发中由于某些原因又不得不用ajax提交文件, 为 ...
- php 学习笔记 数组3
15.使用数组 1).并集(union) array_merge(array1,array2,array3..) 函数把两个或多个数组合并为一个数组,后面覆盖前面 2). 交集(intersecti ...
- 我的Python成长之路---第三天---Python基础(13)---2016年1月16日(雾霾)
五.Python的常用的内置函数 Python为我们准备了大量的内置函数,如下图所示 这里我们只讨论红框内的内置函数 abs(x) 返回一个数的绝对值(模),参数可以是真说或浮点数 >>& ...
- HDU 3899 简单树形DP
题意:一棵树,给出每个点的权值和每条边的长度, 点j到点i的代价为点j的权值乘以连接i和j的边的长度.求点x使得所有点到点x的代价最小,输出 虽然还是不太懂树形DP是什么意思,先把代码贴出来把. 这道 ...
- php前端控制器设计1
The primary role of a front controller in web-based applications is to encapsulate the typical reque ...
- partial_sort_百度百科
partial_sort_百度百科 partial_sort
- android网络编程注意事项之一:移动网络下,防止网络超时甚至连接不上,解决办法--为网络请求设置代理
Android应用程序访问互联网资源时,在Wifi的情况下处理网络连接按照上文所讲述的方法步骤即可顺利实现:但如果当前Android设备的联网方式是通过移动运营商的网络服务为中转,间接访问的互联网资源 ...
- Android中如何查找内存泄露
1.首先确定是否有内存泄露及哪个程序造成. 1.1.内存泄露已弹出out of memory对话框的情况. 这种情况很简单,直接看对话框就知道是哪个应用的问题了.然后再分析该应用是否是因为内存泄露造成 ...