微信公众号:「小林coding」

用简洁的方式,分享编程小知识。

01 ++、--运算符重载函数的格式

自增运算符和自减运算符是有前置和后置之分的,如:

a++  // 后置自增运算符
++a // 前置自增运算符 b-- // 后置自减运算符
--b // 前置自减运算符

为了区分所重载的是前置运算符还是后置运算符,C++规定:

  • 前置运算符作为一元运算符重载,重载为成员函数的格式如下:
T & operator++(); // 前置自增运算符的重载函数,函数参数是空
T & operator--(); // 前置自减运算符的重载函数,函数参数是空
  • 后置运算符作为二元运算符重载,多写一个没用的参数,重载为成员函数的个数如下:
T  operator++(int); // 后置自增运算符的重载函数,多一个没用的参数
T operator--(int); // 后置自减运算符的重载函数,多一个没用的参数

02 讨论前置和后置运算符的返回值

前置和后置运算符重载函数如下:

前置运算符重载的成员函数 后置运算符重载的成员函数
T & operator++(); T operator++(int);
T & operator--(); T operator--(int);

注意到区别了吗?那么问题来了:

  • 为什么前置运算符返回的是引用 &
  • 为什么后置运算符返回的是普通的对象(临时对象)?

主要是因为为了保持原本 C++ 前置和后置运算符的特性:

  • 前置运算符的特性
int a = 0

// (++a) = 5; 可以拆解成:
// a = a + 1;
// a = 5;
(++a) = 5; // 前置++

a 先自增 +1 后, a 的值就为 1 ,然后再参与 a=5 的运算,所以最后 a 的值是 5。

这说明 (++a) 返回的是自增后 a 变量, a 变量在后续运算过程中,a 变量的值会被修改。所以前置运算符的重载函数的返回值必须是引用 &

  • 后置运算符的特性

而后置运算符,是不能作为左值的,也就是 (a++) = 5; 是不成立的,所以后置运算符的重载函数的返回值就是普通的对象。

03 ++、--运算符重载函数的编写

int main()
{
CDemo d(10);
cout << d++ << ","; // 等价于 d.operator++(0);
cout << d << ","; cout << ++d << ","; // 等价于 d.operator++();
cout << d << ","; cout << d-- << ","; // 等价于 d.operator--(0);
cout << d << ","; cout << --d << ","; // 等价于 d.operator--();
cout << d << endl; return 0;
}

输出结果:

10,11,12,12
12,11,10,10

假设要实现如上的 main 函数输出的结果,该如何编写呢?

首先我们先定义好 CDemo 类,同时也把自增、自减运算符重载函数定义好。

class CDemo
{
public:
CDemo(int i = 0):m_num(i) {} // 构造函数 CDemo & operator++(); // 前置自增运算符重载
CDemo operator++(int); // 后置自增运算符重载 CDemo & operator--(); // 前置自减运算符重载
CDemo operator--(int); // 后置自减运算符重载 private:
int m_num; // 成员变量
};

接着继续实现前置自增、自减运算符重载函数:

// 前置++
CDemo & CDemo::operator++()
{
++m_num;
return *this;
} // 前置--
CDemo & CDemo::operator--()
{
--m_num;
return *this;
}

后置自增、自减运算符重载,就有点不同,例如后置++,是先参与运算,再进行自增,所以返回值是没自增前的对象,具体实现如下:

// 后置++
CDemo CDemo::operator++(int)
{
CDemo tmp(*this); // 记录修改前的对象
m_num--;
return tmp; // 返回修改前的对象
} // 后置--
CDemo CDemo::operator--(int)
{
CDemo tmp(*this); // 记录修改前的对象
m_num++;
return tmp; // 返回修改前的对象
}

04 前置和后置运算符的性能比较

从上面的例子,我们看到后置运算符的重载函数的执行步骤:

  1. 先要产生一个临时对象来保存未自增或自减前的对象;
  2. 接着成员变量自增或自减;
  3. 最后返回修改前的对象;

而前置运算符的重载函数的执行步骤:

  1. 成员变量自增或自减;
  2. 返回对象引用;

可见,前置运算符的重载函数是比后置运算符的重载函数性能是更高的,开销相对比较少。

当然对于普通变量类型,如int、double、long等,前置和后置是性能差距是不大的。重要是我们在对于对象和迭代器使用自增或自减时,最好用前置的运算符的方式,这样可以减少开销


C++ 自增、自减运算符的重载和性能分析的更多相关文章

  1. C++学习30 重载++和--(自增自减运算符)

    自增“++”和自减“--”都是一元运算符,它的前置形式和后置形式都可以被重载.请看下面的例子: #include <iostream> #include <iomanip> u ...

  2. 【转】 C语言自增自减运算符深入剖析

    转自:http://bbs.csdn.net/topics/330189207 C语言的自增++,自减--运算符对于初学者来说一直都是个难题,甚至很多老手也会产生困惑,最近我在网上看到一个问题:#in ...

  3. java入门---运算符&算术运算符&自增自减运算符&关系运算符&位运算符

        计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量.我们可以把运算符分成以下几组: 算术运算符 关系运算符 位运算符 逻辑运算符 赋值运算符 ...

  4. java自增(自减)运算符

    自增(自减)运算符: ++ --就是可以将当前变量自我增加(减少)1 的运算符. i++, 后++, 先将 i 的值作为整个表达的值, 然后将 i 增加 1. ++i, 先++, 先将 i 增加 ...

  5. 2-1赋值运算符 & 2-2自增自减运算符 &2-3

    2-1赋值运算符 先定义一个变量,把定义好的变量在赋值给另外一个变量.变向之间的互相赋值 2-2自增自减运算符 元素符,放在变量前和变量后的区别 先进行自增运算,再进行赋值运算.这里先进行num1的+ ...

  6. C语言系列之自增自减运算符的用法(二)

    运算符中最难理解的有自增自减运算符的使用方法,下面我将简单总结一下他们的使用方法 我们知道,C语言运行是由右向左运行的 下面我们来看一个例子 当i等于3的时候 j=++i; 由上面可知,C语言是由右向 ...

  7. c语言:自增自减运算符的操作详解

    博主在回忆c语言的基本知识时,突然发现自增自减运算符(--.++)这个知识点有些模糊不清,故博主为了给同为小白的同学们提供一些经验,特写下这篇文章. 首先,自增自减运算符共有两种操作方式. 比如,我先 ...

  8. 023 01 Android 零基础入门 01 Java基础语法 03 Java运算符 03 算术运算符之——自增自减运算符

    023 01 Android 零基础入门 01 Java基础语法 03 Java运算符 03 算术运算符之--自增自减运算符 本文知识点:Java算术运算符中的自增自减运算符 自增自减运算符 之前我们 ...

  9. 【java从入门到精通】day-06-基本运算符-自增自减运算符

    1.运算符 java语言支持如下运算符: 算术运算符:+,-,*,/,%,++,-- 赋值运算符:= 关系运算符:>,<,>=,<=,==,!=,instanceof 逻辑运算 ...

随机推荐

  1. QLineEdit限制数据类型——只能输入浮点型数

    前言 最近做了一个小的上位机,要通过串口来下发几个时间参数,为了防止误输入,产生不必要的麻烦,我把输入范围限制在0-680的浮点型数据,支持小数点后2位.学习了一下QLineEdit类是如何限制输入类 ...

  2. 关于ASP.NET配置

    字符串加密打开Vs的开发人员命令提示符 //加密web.config文件的连接字符串aspnet_regiis.exe -pef "connectionStrings" " ...

  3. ZooKeeper(三):请求处理链路的创建过程解析

    我们知道,zk就是一个个处理链组成的. 但是,这些处理链是在什么创建的呢? ZooKeeper 中有三种角色的服务节点存在: Leader, Follower, Observer . 而每个服务节点的 ...

  4. JAVAEE学期总结

         声明:除第一张思维导图为博主所制作,其他思维导图皆来自网络,若侵权,望告知,必删除.                                                      ...

  5. 2018简约商务工作汇报工作总结公司培训团队介绍PPT模

    这几款ppt模板都是简约大气类型的,32页足够丰富,有完整结构框架,可以修改文字图片直接套用模板,是通用的商务ppt模板. 模版来源:http://ppt.dede58.com/gongzuohuib ...

  6. Linux-shell学习笔记2

    1.命令的运行顺序 以相对/绝对路径运行命令,例如『 /bin/ls 』或『 ./ls 』: 由 alias 找到该命令来运行: 由 bash 内建的 (builtin) 命令来运行: 通过 $PAT ...

  7. nodejs编写后台

    1.引入核心模块 2.服务器监听窗口 3.创建服务器对象 4.设置服务器监听窗口 寻找路径 // 引入核心模块 const http = require('http') // 服务器监听窗口 cons ...

  8. QJsonObject与QString转化封装

    经常使用QT的同学可能会发现有时候需要json字符串和json对象之间的转换,今天他来了,直接上代码: QString InfoBase::JsonToString(const QJsonObject ...

  9. python Djanjo csrf说明与配置

     Django csrf  CSRF 全称(Cross Site Request Forgery)跨站请求伪造.也被称为One Click Attack和Session Riding,通常缩写为CSR ...

  10. django之查询操作及开启事务

    目录 聚合查询 aggregate 聚合函数 分组查询 annotate F与Q查询 F查询 Q查询 ORM操作事务 django中开启事务 聚合查询 aggregate 操作外键字段管理数据的时候, ...