C++学习笔记之运算符重载
一、运算符重载基本知识
在前面的一篇博文
中,介绍了函数重载的概念,定义及用法,函数重载(也被称之为函数多态)就是使用户能够定义多个名称相同但特征标(参数列表)不同的函数,目的是在对不同类型的参数执行相同的操作时只用一个同名的函数。
运算符重载,就是使同一个运算符在面临不同类型的数据时作出不同的操作(函数重载是操作相同),就是让同一个运算符有多重功能。实际上我们经常用的许多运算符已被重载,例如,将*用于地址,将得到存储在这个地址中的值;但将它用于两个数字时,得到的将是它们的乘积。
C++允许将运算符重载扩展到用户定义的类型,如允许使用+将两个对象相加,编译器根据操作的数目和类型决定使用哪种加法的定义。
运算符重载格式如下:
operator运算符();
例如,operator+()重载+运算符,operator-()重载-运算符等。但是被重载的运算符必须是有效的C++运算符,不能自创一个新的符号。
二、运算符重载示例
假设写一篇博客,上午花了1小时42分钟编码,下午又花了2小时33分钟修改,要计算总共花的时间,很显然与加法概念很吻合,但是要相加的单位是小时与分钟的混合,与内置的加法类型不匹配。采用一个使用方法来处理加法的Time类。作为对比,首先使用常规方法,建立一个名为sum()的函数,然后介绍使用重载运算符。
函数的方法:
- //mytime0,未使用运算符重载
- #ifndef MYTIME0_H
- #define MYTIME0_H
- class Time
- {
- private:
- int hours;
- int minutes;
- public:
- Time();
- Time(int h, int m = );
- void addMin(int m);
- void addHr(int h);
- void reset(int h = , int m = );
- Time sum(const Time & t ) const;
- void show() const;
- };
- #endif
- #include <iostream>
- #include "mytime0.h"
- Time::Time()
- {
- hours = minutes = ;
- }
- Time::Time(int h, int m)
- {
- hours = h;
- minutes = m;
- }
- void Time::addMin(int m)
- {
- minutes += m;
- hours += minutes / ;
- minutes %= ;
- }
- void Time::addHr(int h)
- {
- hours += h;
- }
- void Time::reset(int h, int m)
- {
- hours = h;
- minutes = m;
- }
- Time Time::sum(const Time & t) const
- {
- Time result;
- result.minutes = minutes + t.minutes;
- result.hours = hours + t.hours +result.minutes / ;
- result.minutes %= ;
- return result;
- }
- void Time::show() const
- {
- std::cout << hours << " hours, " << minutes << " minutes";
- }
- /*usetime0*/
- #include <iostream>
- #include "mytime0.h"
- int main()
- {
- using std::cout;
- using std::endl;
- Time planning;
- Time coding(, );
- Time fixing(, );
- Time total;
- cout << "planning time = ";
- planning.show();
- cout << endl;
- cout << "coding time = ";
- coding.show();
- cout << endl;
- cout << "fixing time = ";
- fixing.show();
- cout << endl;
- total = coding.sum(fixing);
- cout << "coding.sum(fixing) = ";
- total.show();
- cout << endl;
- return ;
- }
运行结果:
运算符重载的方法:
这里所举例子比较简答,我们只需要将sum()名称改为operator+()即可。程序清单如下:
- //mytime0,未使用运算符重载
- #ifndef MYTIME0_H
- #define MYTIME0_H
- class Time
- {
- private:
- int hours;
- int minutes;
- public:
- Time();
- Time(int h, int m = );
- void addMin(int m);
- void addHr(int h);
- void reset(int h = , int m = );
- Time operator+(const Time & t ) const;
- void show() const;
- };
- #endif
- #include <iostream>
- #include "mytime0.h"
- Time::Time()
- {
- hours = minutes = ;
- }
- Time::Time(int h, int m)
- {
- hours = h;
- minutes = m;
- }
- void Time::addMin(int m)
- {
- minutes += m;
- hours += minutes / ;
- minutes %= ;
- }
- void Time::addHr(int h)
- {
- hours += h;
- }
- void Time::reset(int h, int m)
- {
- hours = h;
- minutes = m;
- }
- Time Time::operator+(const Time & t) const
- {
- Time result;
- result.minutes = minutes + t.minutes;
- result.hours = hours + t.hours +result.minutes / ;
- result.minutes %= ;
- return result;
- }
- void Time::show() const
- {
- std::cout << hours << " hours, " << minutes << " minutes";
- }
- /*usetime0*/
- #include <iostream>
- #include "mytime0.h"
- int main()
- {
- using std::cout;
- using std::endl;
- Time planning;
- Time coding(, );
- Time fixing(, );
- Time total;
- cout << "planning time = ";
- planning.show();
- cout << endl;
- cout << "coding time = ";
- coding.show();
- cout << endl;
- cout << "fixing time = ";
- fixing.show();
- cout << endl;
- total = coding + fixing; //通过运算符+号直接调用重载的运算符
- cout << "coding + fixing = ";
- total.show();
- cout << endl;
- Time morefixing(, );
- cout << "morefixing time = ";
- morefixing.show();
- cout << endl;
- total = morefixing.operator+(total);//也可以通过函数名的方式调用
- cout << "morefixing.operator+(total) = ";
- total.show();
- cout << endl;
- return ;
- }
总之,operator+()函数名使得可以使用函数表示法或运算符表示法来调用它。
如果t1,t2,t3,t4都是Time对象,可以这样操作吗:
t4 = t1 + t2 +t3;
我们来仔细分析下,+是从左向右结合的运算符,根据上述代码中的函数,上述语句首先被转换为:
- t4 = t1.operator+(t2 + t3); //t1调用operator+()函数
接着继续转换为:
- t4 = t1.operator+(t2.operator+(t3)); //t2调用operator+()函数
上述语句合法吗?当然合法,因为 t2.operator+(t3)返回一个Time对象,是t2和t3的和,该对象又成为函数调用t1.operator+()的参数,该调用返回t1与表示t2和t3之和的Time对象的和。最后返回值为t1,t2,t3之和,正是我们想要的结果。可以看出,运算符重载实现运算功能要比函数看起来更加自然一些。
三、重载的限制
多数C++运算符都可以用这样的方式重载。但是没有绝对的自由。主要限制有如下几条:
- 重载后的运算符至少有一个操作数是用户定义的类型。这将防止用户为标准类型重载运算符。假如没有这个限制,我们可以将-重载为两个double相加,而不是它们的差,就乱套了。
- 使用运算符不能违反运算符原来的句法规则。例如。不能将求模运算符(%)重载成使用一个操作数:% x.同时不能修改运算符的优先级。
- 不能创建新的运算符。例如,不能定义operator**()函数来表示求幂。
- 不能重载如下运算符:
- sizeof sizeof运算符
- . 成员运算符
- .* 成员指针运算符
- :: 作用域解析运算符
- ?: 条件运算符
- typeid 一个RTTI运算符
- const_cast
- dynamic_cast
- reinterpret_cast
- static_cast
5. 大多数运算符都可以通过成员或者非成员函数重载,但是下面的运算符只能通过成员函数重载
= 赋值运算符
() 函数调用运算符
[] 下表运算符
-> 通过指针访问类成员的运算符。
C++学习笔记之运算符重载的更多相关文章
- C++基础 学习笔记五:重载之运算符重载
C++基础 学习笔记五:重载之运算符重载 什么是运算符重载 用同一个运算符完成不同的功能即同一个运算符可以有不同的功能的方法叫做运算符重载.运算符重载是静态多态性的体现. 运算符重载的规则 重载公式 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 重载运算符和重载函数
C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载. 重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不 ...
- 《Inside C#》笔记(十一) 运算符重载
运算符重载与之前的索引器类似,目的是为了让语言本身使用起来更方便直接,也是一种语法糖. 一 运算符重载(Operator Overloading) 运算符重载的存在,使得现有的各种运算符可以被重新定义 ...
- C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对运算符重载的函数有两种处理方式:(1)把运算符 ...
- C++学习之路—运算符重载(一)概念、方法及规则
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 1 什么是运算符重载 先来说下什么是重载吧 ...
- C++ Primer笔记10_运算符重载_赋值运算符_进入/输出操作符
1.颂值运营商 首先来福值运算符引入后面要说的运算符重载.上一节说了构造函数.拷贝构造函数:一个类要想进行更好的控制.须要定义自己的构造函数.拷贝构造函数.析构函数.当然,还有赋值运算符.常说的三大函 ...
- 新标准C++程序设计读书笔记_运算符重载
形式 返回值类型 operator 运算符(形参表) { …… } 运算符重载 (1)运算符重载的实质是函数重载(2)可以重载为普通函数,也可以重载为成员函数 class Complex { publ ...
- scala学习手记7 - 运算符重载
从语法上来说scala是没有运算符的.之前的一节里也曾提到过scala的运算符实际上是方法名,如1 + 2实际上就是1.+(2).我们可以将之视为运算符,是因为scala的一个特性:如果方法的参数小于 ...
- C++ Primer笔记13_运算符重载_总结
总结: 1.不能重载的运算符: . 和 .* 和 ?: 和 :: 和 sizeof 和 typeid 2.重载运算符有两种基本选择: 类的成员函数或者友元函数, 建议规则例如以下: 运算符 建议使用 ...
随机推荐
- ArcGIS 开发的一些知识学习点
由于文章太多,不便转载,现主要列举如下: ArcGIS Runtime支持的GP工具列表 ArcGIS Runtime支持的GP工具列表 目录(?)[-] Standard版本Standard 空间分 ...
- C#中实现对Excel特定文本的搜索
打开Excel的VBA帮助,查看Excel的对象模型,很容易找到完成这个功能需要的几个集合和对象: Application.Workbooks. Workbook.Worksheets还有Worksh ...
- Java之--Java语言基础组成—函数
Java语言基础组成-函数 Java语言由8个模块构成,分别为:关键字.标识符(包名.类名.接口名.常量名.变量名等).注释.常量和变量.运算符.语句.函数.数组. 本片主要介绍Java中的函数,函数 ...
- javascript的变态位运算
javascript的变态位运算 var a = "10" | 0; alert(a); alert (typeof a);结果为10,number. 这就是说这条语句可以将字符串 ...
- jsoup入门
官网地址:http://jsoup.org/ Jsoup是一个开源的Java库,它可以用于处理实际应用中的HTML.它提供了非常便利的API来进行数据的提取及修改,充分利用了 DOM,CSS以及jqu ...
- iOS学习笔记之回调(二)
写在前面 上一篇学习笔记中简单介绍了通过目标-动作对实现回调操作:创建两个对象timer和logger,将logger设置为timer的目标,timer定时调用logger的sayOuch函数.在这个 ...
- 【LeetCode】228 - Summary Ranges
Given a sorted integer array without duplicates, return the summary of its ranges. For example, give ...
- 提供给开发者 10 款最好的 Python IDE
Python 非常易学,强大的编程语言.Python 包括高效高级的数据结构,提供简单且高效的面向对象编程. Python 的学习过程少不了 IDE 或者代码编辑器,或者集成的开发编辑器(IDE).这 ...
- 现代浏览器内置的可等效替代jQuery的功能
jQuery的体积在不断的增大.新功能要不断增加,这是必然结果.虽然从版本1.8.3开始的瘦身效果明显,但不可否认的是,对于移动手机端的网 页开发,它仍然是不可接受的.当然,jQuery不是铁板一块, ...
- How to Keep Alive SSH Sessions
How to Keep Alive SSH Sessions Many NAT firewalls time out idle sessions after a certain period of t ...