C++中前置操作符和后置操作符的重载
1,C 语言中讨论了原生含义,C++ 中有必要考虑前置、后置操作符能够重载,有何问题;
2,值得思考的问题:
1,下面的代码有没有区别?为什么?
1,i++ // i 的值作为返回值,i 自增 1;
2,++i // i 自增 1,i 的值作为返回值;
3,没有使用返回值,由于编译器(不同的编译器都是一样的)的优化,在工程上面,这两行代码没有区别;
2,真的有区别吗?编程实验:
1,main.cpp 文件:
#include <iostream>
#include <string> using namespace std; int main()
{
int i = ; i++; ++i; return ;
}
2,底层对应代码:

1,工程上除了使用的寄存器有差别之外,本质没有什么差别;
2,这是由于编译器的优化,这里是单独存在的、并没有使用它们的返回值,这个时候编译器的优化就是将返回值抛弃,得到的汇编代码就是上述内容;
3,现代编译器中的自增特性:
1,现代编译器产品会对代码进行优化;
2,优化使得最终的二进制程序更加高效;
3,优化后的二进制程序丢失了 C/C++ 的原生语义;
4,不可能从编译后的二进制程序还原 C/C++ 程序;
4,思考:
1,++ 操作符可以重载吗?如何区分前置 ++ 和后置 ++ ?
1,可以,-- 操作符也可以;
5,++ 操作符重载:
1,++ 操作符可以被重载:
1,全局函数和成员函数局可以进行重载;
2,重载前置 ++ 操作符不需要额外的参数;
3,重载后置 ++ 操作符需要一个 int 类型的占位参数;
2,++ 操作符的重载编程实验:
1,main.cpp 文件:
#include <iostream>
#include <string> using namespace std; class Test
{
int mValue;
public:
Test(int i)
{
mValue = i;
} int value()
{
return mValue;
} Test& operator ++ () // ++ 后返回自身;
{
++mValue; // 先将当前操作数加 1; return *this; // 加 1 后返回当前的操作数;
} /* 若这个操作符不实现,则编译器显示:error: no 'operator++(int) declared for poatfix '++', try prefix operator instead */
/* C 语言中定义,如果是后置 ++,它先将当前操作数值保存在临时对象中;于是这里借助局部对象 ret 保存下来,之后返回 */
Test operator ++ (int) // 占位参数为 int 类型;
{
Test ret(mValue);// ++ 之前的值先返回,当然这里先存储着返回值,之后再 ++; mValue++; // 然后 ++ return ret;
}
}; int main()
{
Test t(); t++; ++t; return ;
}
2,上述 main() 中的两行加加代码,因为调用函数不一样,所以有差异,并 且前置 ++ 效率更高,因为它的实现没有生成额外的对象,意味着不需要过 多的栈内存,不需要调用构造、析构函数;
6,真正的区别(本博文2 中的思考):
1,对于基础类型的变量:
1,前置 ++ 的效率与后置 ++ 的效率基本相同;
1,编译器会优化;
2,根据项目组编码规范进行选择;
2,对于类类型的对象:
1,前置 ++ 的效率高于后置 ++;
2,尽量使用前置 ++ 操作符提高程序效率;
7,复数类的进一步完善 class Complex 编程实验:
1,Complex.h 文件:
#ifndef _COMPLEX_H_
#define _COMPLEX_H_ class Complex
{
double a;
double b;
public:
Complex(double a = , double b = );
double getA();
double getB();
double getModulus(); Complex operator + (const Complex& c);
Complex operator - (const Complex& c);
Complex operator * (const Complex& c);
Complex operator / (const Complex& c); bool operator == (const Complex& c);
bool operator != (const Complex& c); Complex& operator = (const Complex& c); /* 本博文重载了下面两个操作符 */
Complex& operator ++ ();
Complex operator ++ (int);
};
2,Complex.cpp 文件:
#include "Complex.h"
#include "math.h" Complex::Complex(double a, double b)
{
this->a = a;
this->b = b;
} double Complex::getA()
{
return a;
} double Complex::getB()
{
return b;
} double Complex::getModulus()
{
return sqrt(a * a + b * b);
} Complex Complex::operator + (const Complex& c)
{
double na = a + c.a;
double nb = b + c.b;
Complex ret(na, nb); return ret;
} Complex Complex::operator - (const Complex& c)
{
double na = a - c.a;
double nb = b - c.b;
Complex ret(na, nb); return ret;
} Complex Complex::operator * (const Complex& c)
{
double na = a * c.a - b * c.b;
double nb = a * c.b + b * c.a;
Complex ret(na, nb); return ret;
} Complex Complex::operator / (const Complex& c)
{
double cm = c.a * c.a + c.b * c.b;
double na = (a * c.a + b * c.b) / cm;
double nb = (b * c.a - a * c.b) / cm;
Complex ret(na, nb); return ret;
} bool Complex::operator == (const Complex& c)
{
return (a == c.a) && (b == c.b);
} bool Complex::operator != (const Complex& c)
{
return !(*this == c);
} Complex& Complex::operator = (const Complex& c)
{
if( this != &c )
{
a = c.a;
b = c.b;
} return *this;
} Complex& Complex::operator ++ ()
{
a = a + ;
b = b + ; return *this;
} Complex Complex::operator ++ (int)
{
Complex ret(a, b); a = a + ;
b = b + ; return ret;
} #endif
8,小结:
1,编译优化使得最终的可执行程序更加高效;
2,前置 ++ 操作符和后置 ++ 操作符都可以被重载;
3,++ 操作符的重载必须符合其原生语义;
4,对于基础类型,前置 ++ 与后置 ++ 的效率几乎相同;
5,对于类类型,前置 ++ 的效率高于后置 ++;
1,对于类类型,工程中尽量使用前置 ++;
C++中前置操作符和后置操作符的重载的更多相关文章
- C++语法小记---前置操作符和后置操作符
前置操作符和后置操作符 单独的"++i"和"i++"是否有区别 对于基本类型: 二者没有区别,因为编译器会对代码进行优化,二者的汇编代码完全相同 对于类类型: ...
- SQL中前置0和后置0的处理问题
在sql语句中经常遇到处理前置和后置数据的问题 1.首先使用convert转化函数对预处理的数据进行转化,CONVERT()函数可以将制定的数据类型转换为另一种数据类型 MySQL 的CAST()和C ...
- eas之dep的前置脚本和后置脚本
dep的前置脚本和后置脚本,什么时候写,是这样解释的: 前置脚本是在方法前执行,后置脚本是在方法后执行 1.比如保存扩展,如果你要在保存前校验某个字段的值,你要在前置脚本中写,如果要保存后 ...
- Thinkphp入门 二 —空操作、空模块、模块分组、前置操作、后置操作、跨模块调用(46)
原文:Thinkphp入门 二 -空操作.空模块.模块分组.前置操作.后置操作.跨模块调用(46) [空操作处理] 看下列图: 实际情况:我们的User控制器没有hello()这个方法 一个对象去访问 ...
- thinkPHP 空模块和空操作、前置操作和后置操作 详细介绍(十四)
原文:thinkPHP 空模块和空操作.前置操作和后置操作 详细介绍(十四) 本章节:介绍 TP 空模块和空操作.前置操作和后置操作 详细介绍 一.空模块和空操作 1.空操作 function _em ...
- thinkPHP 空模块和空操作、前置操作和后置操作 具体介绍(十四)
本章节:介绍 TP 空模块和空操作.前置操作和后置操作 具体介绍 一.空模块和空操作 1.空操作 function _empty($name){ $this->show("$name ...
- Pytest里面的测试用例怎么进行前置准备和后置清理操作?
Pytest处理前置后置有两种方式可以处理. 第一种是通过setup和teardown这样的方法去处理: 第二种是通过fixture来实现的.首先先定义fixture,然后在调用.定义fixture, ...
- [原创]java WEB学习笔记106:Spring学习---AOP的通知 :前置通知,后置通知,返回通知,异常通知,环绕通知
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Spring aop——前置增强和后置增强 使用注解Aspect和非侵入式配置
AspectJ是一个面向切面的框架,它扩展了java语言,定义了AOP语法,能够在编译期提供代码的织入,所以它有一个专门的编译器用来生成遵守字节码字节编码规范的Class文件 确保使用jdk为5.0以 ...
随机推荐
- Java多线程和并发(九),ReentrantLock(公平锁)
目录 1.ReentrantLock 2.ReentrantLock的实现 3.synchronized和ReentrantLock的区别 九.ReentrantLock(公平锁) 1.Reentra ...
- 收藏一个bit模板使用实例
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define MAX_N 1000000 int b ...
- CF1205C Palindromic Paths
题目链接 问题分析 首先可以想到,坐标和为奇数的位置可以被唯一确定.同样的,如果假定\((1,2)\)是\(0\),那么坐标和为偶数的位置也可以被唯一确定.这样总共使用了\(n^2-3\)次询问. 那 ...
- Spring boot之JPA
JPA 步骤: (1)在pom.xml添加mysql,spring-data-jpa依赖 (2)在application.properties文件中配置mysql连接配置文件 (3)在applicat ...
- C++入门经典-例3.18-使用for循环计算从1到10的累加
1:代码如下: // 3.18.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...
- [翻译]剖析C#中的异步方法
翻译自一篇博文,原文:Dissecting the async methods in C# 有些括号里的是译注或我自己的理解. 异步系列 剖析C#中的异步方法 扩展C#中的异步方法 C#中异步方法的性 ...
- Scala学习(四)——模式匹配与函数组合
函数组合 让我们创建两个函数: def f(s: String) = "f(" + s + ")" def g(s: String) = "g(&qu ...
- 黑马lavarel教程---7、文件上传
黑马lavarel教程---7.文件上传 一.总结 一句话总结: 在laravel里面实现文件的上传是很简单的,压根不用引入第三方的类库,作者把上传作为一个简单的http请求看待的. 1.在lavar ...
- ffmpeg循环推流
ffmpeg循环推流 有时候需要轮播出一路直播 这个时候循环推流就比较方便了 ffmpeg -stream_loop - -re -i d:/Media/a.ts -vcodec h264 -acod ...
- electron--Tray添加图标和上下文菜单到系统通知区(系统托盘)
const { app, Menu, Tray } = require('electron'); //系统托盘图标目录 appTray = new Tray(path.join(__dirname, ...