【C++】运算符重载
运算符重载,主要是简化类类型运算,能够让我们对类对象直接用运算符进行运算。基本语法:
- 类型 operator 运算符(参数列表){ ... }
- Complex operator+(Complex var1, Complex var2){ ... }
简单地说,就是给类对象定义自己的加减乘除等等操作符。同时,作为为了类对象的操作而重载的运算符,它是类的成员函数,或者含有至少一个类类型参数,例如:
(VS2013)
另外,重载运算符分两种①重载运算符是类的成员函数;②重载运算符不是类的成员函数,简单地说就是重载定义在类的内部还是外部,这两种情况是有很大区别的,例如,我自己定义的一个复数Complex类,并为其重载加法运算符:
- class Complex
- {
- public:
- int a, b;
- void input(string s){
- int v1 = ;
- int i = ;
- while (s[i] != '+'){
- v1 = v1 * + s[i] - '';
- i++;
- }
- while (s[i] == ' ' || s[i] == '+' || s[i] == 'i'){
- i++;
- }
- int v2 = ;
- while (i<s.length()){
- v2 = v2 * + s[i] - '';
- i++;
- }
- a = v1;
- b = v2;
- }
- /*========== 重载运算符为类成员函数 =============*/
- Complex operator+(Complex var){ //参数列表里只有一个参数,this被绑定到左侧运算对象
- //即第一个运算对象是this
- int a1 = a; // a1 = this->a
- int b1 = b;
- int a2 = var.a;
- int b2 = var.b;
- Complex sumResult;
- sumResult.a = a1 + a2;
- sumResult.b = b1 + b2;
- return sumResult;
- }
- /*===============================================*/
- };
- /*========== 重载运算符不是类成员函数 =============*/
- Complex operator+(Complex var1, Complex var2){ //基本形式与函数定义相同
- int a1 = var1.a;
- int b1 = var1.b;
- int a2 = var2.a;
- int b2 = var2.b;
- Complex sumResult;
- sumResult.a = a1 + a2;
- sumResult.b = b1 + b2;
- return sumResult;
- }
- /*===============================================*/
那么,在重载运算符的时候,如何选择将其声明为非成员函数还是声明为类成员函数呢?
- 赋值(=),下标([]),调用(()),成员访问(->)必须是成员函数;
- 复合赋值运算符和形如递增、递减和解引用等改变对象状态或与类型密切相关的运算符,一般定义为成员函数(非必须);
- 具有对称性运算符可能转换任一端运算对象,如算术(加减乘除etc)、相等性、关系和位运算符等,通常定义为非成员函数。
另外,如果参数含有类对象的混合表达式,必须定义成非成员函数。
(C++ primer P493)
运算符 | note | |
输出<< | 一般第一个形参是非常量ostream对象的引用,不要打印换行符 | 必须是非成员函数 |
输入>> | 第一个参数为读取流的引用,第二个参数是要读进去的非常量对象的引用,得检查读入是否成功 | 必须是非成员函数 |
算术+-*/ | 一般,形参为常量引用 | 可以是非成员函数 |
相等== | 定义了==,应该也要有一个!= | 可以是非成员函数 |
小于< | 不是每个类都能定义一个< | 可以是非成员函数 |
赋值= | 要先销毁被赋值对象(左侧运算对象)当前的内存空间,再创建新空间存放新的赋值,返回被赋值对象的引用 | 必须是成员函数 |
复合赋值 +=、-= | 返回左侧运算对象的引用 | 一般是成员函数 |
下标[] | 返回所访问元素的引用(这样[]就可以出现在赋值运算符的任意一端);最好同时定义[]的常量版本和非常量版本 | 必须是成员函数 |
另外还有几个重载比较复杂的:
1、递增++/递减--运算符:
- 要同时定义前置版本和后置版本;
- 需要调用check函数检验对象是否有效;
- 后置版本接受一个额外int类型形参(不被使用),需要在递增/递减对象之前记录之前的状态(后置递增返回值还是递增之前的值),后置版本要调用前置版本完成;
- 显示调用:
- 前置:p.operator++()【等价于++p】;
- 后置:p.operator++(0)【等价于p++】
2、成员访问运算符*、->:
3、函数调用运算符():
【C++】运算符重载的更多相关文章
- C++ 运算符重载时,将运算符两边对象交换问题.
在C++进行运算符重载时, 一般来讲,运算符两边的对象的顺序是不能交换的. 比如下面的例子: #include <iostream> using namespace std; class ...
- C#高级编程笔记2016年10月12日 运算符重载
1.运算符重载:运算符重重载的关键是在对象上不能总是只调用方法或属性,有时还需要做一些其他工作,例如,对数值进行相加.相乘或逻辑操作等.例如,语句if(a==b).对于类,这个语句在默认状态下会比较引 ...
- C++运算符重载
C++运算符重载 基本知识 重载的运算符是具有特殊名字的函数,他们的名字由关键字operator和其后要定义的运算符号共同组成. 运算符可以重载为成员函数和非成员函数.当一个重载的运算符是成员函数时, ...
- 标准C++之运算符重载和虚表指针
1 -> *运算符重载 //autoptr.cpp #include<iostream> #include<string> using namespace std ...
- python运算符重载
python运算符重载就是在解释器使用对象内置操作前,拦截该操作,使用自己写的重载方法. 重载方法:__init__为构造函数,__sub__为减法表达式 class Number: def __in ...
- PoEduo - C++阶段班【Po学校】-Lesson03-5_运算符重载- 第7天
PoEduo - Lesson03-5_运算符重载- 第7天 复习前面的知识点 空类会自动生成哪些默认函数 6个默认函数 1 构造 2 析构 3 赋值 4 拷贝构造 5 oper ...
- 不可或缺 Windows Native (24) - C++: 运算符重载, 自定义类型转换
[源码下载] 不可或缺 Windows Native (24) - C++: 运算符重载, 自定义类型转换 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 运算符重载 自 ...
- 我的c++学习(8)运算符重载和友元
运算符的重载,实际是一种特殊的函数重载,必须定义一个函数,并告诉C++编译器,当遇到该运算符时就调用此函数来行使运算符功能.这个函数叫做运算符重载函数(常为类的成员函数). 方法与解释 ◆ 1.定义运 ...
- c/c++面试题(6)运算符重载详解
1.操作符函数: 在特定条件下,编译器有能力把一个由操作数和操作符共同组成的表达式,解释为对 一个全局或成员函数的调用,该全局或成员函数被称为操作符函数.该全局或成员函数 被称为操作符函数.通过定义操 ...
- 实验12:Problem H: 整型数组运算符重载
Home Web Board ProblemSet Standing Status Statistics Problem H: 整型数组运算符重载 Problem H: 整型数组运算符重载 Tim ...
随机推荐
- Android开源框架:AndroidAnnotations
AndroidAnnotations首页 github上的项目地址AndroidAnnotations Github. wiki:https://github.com/excilys/androida ...
- 洛谷 P1908 逆序对 Label:归并排序||树状数组 不懂
题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定 ...
- 【BZOJ】3339: Rmq Problem & 3585: mex(线段树+特殊的技巧)
http://www.lydsy.com/JudgeOnline/problem.php?id=3585 好神的题. 但是!!!!!!!!!!!!!!我线段树现在要开8倍空间才能过!!!!!!!!!! ...
- sql中的视图
视图可分为:普通视图和索引视图视图的作用: 1.提高数据库的安全性,降低数据库被攻击的风险,使外界无法得知数据库的数据结构 2.使查询更方便,简化程序员的操作非只读视图可以增删改,但不建议.视图的试用 ...
- NOIP200003方格取数
NOIP200003方格取数 难度级别: D: 编程语言:不限:运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 XYZ 是首师大附中信息技术团编 ...
- Java/Js下使用正则表达式匹配嵌套Html标签
转自:http://www.jb51.net/article/24422.htm 以前写过一篇文章讲解如何使用正则表达式完美解决Html嵌套标签的匹配问题(使用正则表达式匹配嵌套Html标签),但是里 ...
- Grasshopper 2.0 MP Color FireWire 1394b (Sony ICX274)
相机参数如下,参见这里: Resolution 1624 x 1224 Frame Rate 30 FPS Megapixels 2.0 MP Chroma Color Sensor Name ...
- OpenCV学习笔记——图像的腐蚀与膨胀
顺便又复习了一下cvcopy如何进行图像拼接(最近觉得打开多幅图像分别看不如缩小掉放拼接到一幅图像上对比来的好) 首先把拼接的目标图像设置兴趣区域ROI,比如我有一个total,要把a.b.c分别从左 ...
- Apache Spark源码走读之9 -- Spark源码编译
欢迎转载,转载请注明出处,徽沪一郎. 概要 本来源码编译没有什么可说的,对于java项目来说,只要会点maven或ant的简单命令,依葫芦画瓢,一下子就ok了.但到了Spark上面,事情似乎不这么简单 ...
- mysq数据库再次理解
1.表中的一条记录就是一个object,object有很多属性,对应表中的字段.object的属性对应的值就是字段值 2.外键是关联表关系用的.表关系的确立只能通过外键 但更高效的策略是,在数据库中部 ...