C++中前置操作符和后置操作符的重载

1,C 语言中讨论了原生含义,C++ 中有必要考虑前置、后置操作符能够重载,有何问题;

2,值得思考的问题:

1,下面的代码有没有区别?为什么?

1,i++  // i 的值作为返回值,i 自增 1;

2,++i  // i 自增 1,i 的值作为返回值;

3,没有使用返回值,由于编译器(不同的编译器都是一样的)的优化,在工程上面,这两行代码没有区别;

2,真的有区别吗?编程实验:

1,main.cpp 文件:

 1 #include <iostream>
 2 #include <string>
 3
 4 using namespace std;
 5
 6 int main()
 7 {
 8     int i = 0;
 9
10     i++;
11
12     ++i;
13
14     return 0;
15 }

  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 文件:

 1 #include <iostream>
 2 #include <string>
 3
 4 using namespace std;
 5
 6 class Test
 7 {
 8     int mValue;
 9 public:
10     Test(int i)
11     {
12         mValue = i;
13     }
14
15     int value()
16     {
17         return mValue;
18     }
19
20     Test& operator ++ ()  // ++ 后返回自身;
21     {
22         ++mValue;  // 先将当前操作数加 1;
23
24         return *this;  // 加 1 后返回当前的操作数;
25     }
26
27     /* 若这个操作符不实现,则编译器显示:error: no ‘operator++(int) declared for poatfix ‘++‘, try prefix operator instead */
28     /* C 语言中定义,如果是后置 ++,它先将当前操作数值保存在临时对象中;于是这里借助局部对象 ret 保存下来,之后返回 */
29     Test operator ++ (int)  // 占位参数为 int 类型;
30     {
31         Test ret(mValue);// ++ 之前的值先返回,当然这里先存储着返回值,之后再 ++;
32
33         mValue++;  // 然后 ++
34
35         return ret;
36     }
37 };
38
39 int main()
40 {
41     Test t(0);
42
43     t++;
44
45     ++t;
46
47     return 0;
48 }

  2,上述 main() 中的两行加加代码,因为调用函数不一样,所以有差异,并 且前置 ++ 效率更高,因为它的实现没有生成额外的对象,意味着不需要过  多的栈内存,不需要调用构造、析构函数;

6,真正的区别(本博文2 中的思考):

1,对于基础类型的变量:

1,前置 ++ 的效率与后置 ++ 的效率基本相同;

1,编译器会优化;

2,根据项目组编码规范进行选择;

2,对于类类型的对象:

1,前置 ++ 的效率高于后置 ++;

2,尽量使用前置 ++ 操作符提高程序效率;

7,复数类的进一步完善 class Complex 编程实验:

1,Complex.h 文件:

 1 #ifndef _COMPLEX_H_
 2 #define _COMPLEX_H_
 3
 4 class Complex
 5 {
 6     double a;
 7     double b;
 8 public:
 9     Complex(double a = 0, double b = 0);
10     double getA();
11     double getB();
12     double getModulus();
13
14     Complex operator + (const Complex& c);
15     Complex operator - (const Complex& c);
16     Complex operator * (const Complex& c);
17     Complex operator / (const Complex& c);
18
19     bool operator == (const Complex& c);
20     bool operator != (const Complex& c);
21
22     Complex& operator = (const Complex& c);
23
24     /* 本博文重载了下面两个操作符 */
25     Complex& operator ++ ();
26     Complex operator ++ (int);
27 };

 2,Complex.cpp 文件:

  1 #include "Complex.h"
  2 #include "math.h"
  3
  4 Complex::Complex(double a, double b)
  5 {
  6     this->a = a;
  7     this->b = b;
  8 }
  9
 10 double Complex::getA()
 11 {
 12     return a;
 13 }
 14
 15 double Complex::getB()
 16 {
 17     return b;
 18 }
 19
 20 double Complex::getModulus()
 21 {
 22     return sqrt(a * a + b * b);
 23 }
 24
 25 Complex Complex::operator + (const Complex& c)
 26 {
 27     double na = a + c.a;
 28     double nb = b + c.b;
 29     Complex ret(na, nb);
 30
 31     return ret;
 32 }
 33
 34 Complex Complex::operator - (const Complex& c)
 35 {
 36     double na = a - c.a;
 37     double nb = b - c.b;
 38     Complex ret(na, nb);
 39
 40     return ret;
 41 }
 42
 43 Complex Complex::operator * (const Complex& c)
 44 {
 45     double na = a * c.a - b * c.b;
 46     double nb = a * c.b + b * c.a;
 47     Complex ret(na, nb);
 48
 49     return ret;
 50 }
 51
 52 Complex Complex::operator / (const Complex& c)
 53 {
 54     double cm = c.a * c.a + c.b * c.b;
 55     double na = (a * c.a + b * c.b) / cm;
 56     double nb = (b * c.a - a * c.b) / cm;
 57     Complex ret(na, nb);
 58
 59     return ret;
 60 }
 61
 62 bool Complex::operator == (const Complex& c)
 63 {
 64     return (a == c.a) && (b == c.b);
 65 }
 66
 67 bool Complex::operator != (const Complex& c)
 68 {
 69     return !(*this == c);
 70 }
 71
 72 Complex& Complex::operator = (const Complex& c)
 73 {
 74     if( this != &c )
 75     {
 76         a = c.a;
 77         b = c.b;
 78     }
 79
 80     return *this;
 81 }
 82
 83 Complex& Complex::operator ++ ()
 84 {
 85     a = a + 1;
 86     b = b + 1;
 87
 88     return *this;
 89 }
 90
 91 Complex Complex::operator ++ (int)
 92 {
 93     Complex ret(a, b);
 94
 95     a = a + 1;
 96     b = b + 1;
 97
 98     return ret;
 99 }
100
101 #endif

8,小结:

1,编译优化使得最终的可执行程序更加高效;

2,前置 ++ 操作符和后置 ++ 操作符都可以被重载;

3,++ 操作符的重载必须符合其原生语义;

4,对于基础类型,前置 ++ 与后置 ++ 的效率几乎相同;

5,对于类类型,前置 ++ 的效率高于后置 ++;

1,对于类类型,工程中尽量使用前置 ++;

原文地址:https://www.cnblogs.com/dishengAndziyu/p/10913920.html

时间: 2024-11-10 02:56:08

C++中前置操作符和后置操作符的重载的相关文章

C++--前置操作符与后置操作符

一.前置操作符与后置操作符 Q:下面的代码有没有区别?为什么?代码的实现 #include <iostream> #include <string> using namespace std; int main() { int i = 0; i++; ++i; return 0; } 意想不到的事实1.现代编译器都会对代码进行优化2.优化使得最终的二进制程序更加高效3.优化后的二进制程序丢失了C/C++的原生语义4.不可能从编译后的二进制程序还原C/C++程序 Q:++操作符可以重载

第四十课、前置操作符和后置操作符

一.i++和++i有没有区别? 1.现代编译器产品会对代码进行优化 2.优化使得最终二进制程序更加高效 3.优化后的二进制程序丢失了c/c++的原生语义 4.不可能从编译后的二进制程序还原c/c++程序 //由此可知,单行的i++和++i在汇编层的代码完全一样 int i = 0; 0123136E mov dword ptr [i],0 i++; 01231375 mov eax,dword ptr [i] 01231378 add eax,1 0123137B mov dword ptr [

第40课 前置操作符和后置操作符

1. ++i和i++真的有区别吗? (1)现代编译器会对代码进行优化.对于基础类型,前置++和后置++的汇编代码几乎是一样的,最终效率完全一样. (2)优化使得最终的二进制程序更加高效 (3)优化后的二进制程序丢失了C/C++的原生语义. (4)不可能从编译后的二进制程序还原C/C++程序. int i = 0; 013612FB mov dword ptr [i],0 i++; 01361302 mov eax,dword ptr [i] 01361305 add eax,1 01361308

前置操作符 后置操作符

++操作符的重载 1.全局函数和成员函数都可以进行重载. 2.前置++操作符不需要参数. 3.后置++操作符需要int类型的占位参数(区分前置后置). #include <iostream> #include <string> using namespace std; class Test { int mValue; public: Test(int i) { mValue = i; } int value() { return mValue; } Test& operat

Thinkphp入门 二 —空操作、空模块、模块分组、前置操作、后置操作、跨模块调用(46)

原文:Thinkphp入门 二 -空操作.空模块.模块分组.前置操作.后置操作.跨模块调用(46) [空操作处理] 看下列图: 实际情况:我们的User控制器没有hello()这个方法 一个对象去访问这个类不存在的方法,那么它会去访问”魔术方法__call()” 用户访问一个不存在的操作—>解决:给每个控制器都定义个_empty()方法来处理 第二个解决方法:定义一个空操作 [空模块处理] 我们使用一个类,但是现在这个类还没有被include进来. 我们可以通过自动加载机制处理__autoloa

thinkPHP 空模块和空操作、前置操作和后置操作 具体介绍(十四)

本章节:介绍 TP 空模块和空操作.前置操作和后置操作 具体介绍 一.空模块和空操作 1.空操作 function _empty($name){ $this->show("$name 不存在 <a href='__APP__/Index/index'>返回首页</a>"); } 2.空模块(EmptyAction.class.php的文件) class EmptyAction extends Action{ function index(){ //$thi

thinkPHP 空模块和空操作、前置操作和后置操作 详细介绍(十四)

本章节:介绍 TP 空模块和空操作.前置操作和后置操作 详细介绍 一.空模块和空操作 1.空操作 function _empty($name){ $this->show("$name 不存在 <a href='__APP__/Index/index'>返回首页</a>"); } 2.空模块(EmptyAction.class.php的文件) class EmptyAction extends Action{ function index(){ //$thi

More Effective C++ 条款6 区别 increment/decrement 操作符的前置(prefix)和后置(postfix)形式

1. 由于前自增和后自增操作符都是一元运算符,因此重载时通过在后自增中加一个int型参数(哑元参数)加以区分,当后自增被调用时,编译器自动在为该参数指定一个0值. 2. 前自增操作符返回调用它的对象的引用,后自增操作符返回const 临时对象 3. 由于前自增是返回的是原对象的引用,因而可以执行类似于++++a这样的式子: 但是后自增返回的是调用后自增操作符之前的对象的副本,如果后自增操作符返回的临时对象不是const,那么就可能会出现a++++的现象,而第二个++作用的其实是一个临时对象,这显

[原创]java WEB学习笔记106:Spring学习---AOP的通知 :前置通知,后置通知,返回通知,异常通知,环绕通知

1.通知分类: @Before: 前置通知, 在方法执行之前执行 @After: 后置通知, 在方法执行之后执行 @AfterRunning: 返回通知, 在方法返回结果之后执行 @AfterThrowing: 异常通知, 在方法抛出异常之后 @Around: 环绕通知, 围绕着方法执行 关于方法签名 看第五点 2.前置通知 3.后置通知:在后置通知中,不能访问目标方法执行的结果          4.返回通知               5.异常通知 6.环绕通知 1 package com.