免费预览已结束,剩余1页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
软件英才网 软件行业驰名招聘网站用汇编的眼光看C+(之算术符重载) 算术符重载是类的有一个特性,但是每个人使用的方法不一样。用的好,则事半功倍;但是如果不正确的使用,则会后患无穷。 (1) 简单算术符介绍 那什么是算术符重载呢?我们可以举个例子。一般来说,我们定义两个int类型的变量的话,我们就可应对这两个类型进行加、减、乘、除的操作,同时还能比较判断、打印、数组操作、*号操作等等。那么如果我们想自己定义的类也具有这样的属性,那我们应该怎么办呢?当然就要算术符重载了。首先,我们对基本class做一个定义:cpp view plaincopy1 class desk 2 3 public: 4 int price; 5 6 desk(int value):price(value) 7 desk() 8 desk& operator+= (desk& d) 9 this-price += d.price; 10 return *this; 11 12 ; 下面,可以用一个范例函数说明一下使用的方法:cpp view plaincopy13 74: desk n(5); 14 0040126D push 5 15 0040126F lea ecx,ebp-10h 16 00401272 call ILT+0(desk:desk) (00401005) 17 00401277 mov dword ptr ebp-4,0 18 75: desk m(10); 19 0040127E push 0Ah 20 00401280 lea ecx,ebp-14h 21 00401283 call ILT+0(desk:desk) (00401005) 22 00401288 mov byte ptr ebp-4,1 23 76: n += m; 24 0040128C lea eax,ebp-14h 25 0040128F push eax 26 00401290 lea ecx,ebp-10h 27 00401293 call ILT+40(desk:operator+=) (0040102d) 28 77: 大家可以把重点放在76句上面,不过74、75句我们也会稍微介绍一下: 74句: 创建desk类型的临时变量n,调用构造函数 75句: 创建desk类型的临时变量m,调用构造函数 76句: 两个desk类型的数据相加,但是在汇编的形式上面,我们发现编译器把这段代码解释成函数调用,也就是我们在上面定义的算术符重载函数。 (2)new、free重载 在C+里面,我们不光可以对普通的算术符进行重载处理,还能对new、free进行重载。通过重载new、free,我们还可以加深对代码的认识,正确认识构造、析构、堆内存分配的原理。 首先,我们对new和delete进行重载定义:cpp view plaincopy29 class desk 30 31 public: 32 int price; 33 34 desk(int value):price(value) 35 desk() 36 void* operator new(size_t size) return malloc(size); 37 void operator delete (void* pData) if(NULL != pData) free(pData); 38 ; 那么使用呢?cpp view plaincopy39 72: desk* d = new desk(10); 40 0040127D push 4 41 0040127F call ILT+65(desk:operator new) (00401046) 42 00401284 add esp,4 43 00401287 mov dword ptr ebp-18h,eax 44 0040128A mov dword ptr ebp-4,0 45 00401291 cmp dword ptr ebp-18h,0 46 00401295 je process+56h (004012a6) 47 00401297 push 0Ah 48 00401299 mov ecx,dword ptr ebp-18h 49 0040129C call ILT+5(desk:desk) (0040100a) 50 004012A1 mov dword ptr ebp-24h,eax 51 004012A4 jmp process+5Dh (004012ad) 52 004012A6 mov dword ptr ebp-24h,0 53 004012AD mov eax,dword ptr ebp-24h 54 004012B0 mov dword ptr ebp-14h,eax 55 004012B3 mov dword ptr ebp-4,0FFFFFFFFh 56 004012BA mov ecx,dword ptr ebp-14h 57 004012BD mov dword ptr ebp-10h,ecx 58 73: delete d; 59 004012C0 mov edx,dword ptr ebp-10h 60 004012C3 mov dword ptr ebp-20h,edx 61 004012C6 mov eax,dword ptr ebp-20h 62 004012C9 mov dword ptr ebp-1Ch,eax 63 004012CC cmp dword ptr ebp-1Ch,0 64 004012D0 je process+91h (004012e1) 65 004012D2 push 1 66 004012D4 mov ecx,dword ptr ebp-1Ch 67 004012D7 call ILT+0(desk:scalar deleting destructor) (00401005) 68 004012DC mov dword ptr ebp-28h,eax 69 004012DF jmp process+98h (004012e8) 70 004012E1 mov dword ptr ebp-28h,0 71 74: 上面是一段普通的new、delete使用代码。但是我们发现,简单的一个语句,在汇编器看来,却需要做这么多的内容,这是为什么呢,我们不妨来自习看一看: 72句:汇编中有两个函数调用,一个是new调用,也就是我们重定义的new函数,一个是构造函数,最后的几行代码主要是把构造函数返回指针赋值给一些临时变量,可忽略 73句:汇编中首先让指针和0进行了判断,然后调用了一个函数,似乎没有调用我们的delete函数,我们可以跟进去看一下:cpp view plaincopy72 desk:scalar deleting destructor: 73 00401410 push ebp 74 00401411 mov ebp,esp 75 00401413 sub esp,44h 76 00401416 push ebx 77 00401417 push esi 78 00401418 push edi 79 00401419 push ecx 80 0040141A lea edi,ebp-44h 81 0040141D mov ecx,11h 82 00401422 mov eax,0CCCCCCCCh 83 00401427 rep stos dword ptr edi 84 00401429 pop ecx 85 0040142A mov dword ptr ebp-4,ecx 86 0040142D mov ecx,dword ptr ebp-4 87 00401430 call ILT+75(desk:desk) (00401050) 88 00401435 mov eax,dword ptr ebp+8 89 00401438 and eax,1 90 0040143B test eax,eax 91 0040143D je desk:scalar deleting destructor+3Bh (0040144b) 92 0040143F mov ecx,dword ptr ebp-4 93 00401442 push ecx 94 00401443 call ILT+80(desk:operator delete) (00401055) 95 00401448 add esp,4 96 0040144B mov eax,dword ptr ebp-4 97 0040144E pop edi 98 0040144F pop esi 99 00401450 pop ebx 100 00401451 add esp,44h 101 00401454 cmp ebp,esp 102 00401456 call _chkesp (00408810) 103 0040145B mov esp,ebp 104 0040145D pop ebp 105 0040145E ret 4 上面的代码便是跟到0x401005之后遇到的代码,这里有一个跳转,真正函数开始的地方是0x401410。这里我们发现函数实际上还是调用了我们定义的delete函数和desk的析构函数。只不过析构函数一定要放在delete调用之前。所以,这里我们就看到了,c+中new的真正含义就是先分配内存,然后调用构造函数;而delete则是先对变量进行析构处理,然后free内存,这就是new和delete的全部意义。掌握了这个基础,可以帮助我们本地对内存进行很好的管理。 (3)friend算术符重载和普通算术符重载的区别 有一种算术符的重载是这样的:cpp view plaincopy106 class desk 107 108 int price; 109 public: 110 desk(int value):price(value) 111 desk() 112 friend desk operator+ (desk& d1, desk& d2); 113 ; 114 115 desk operator +(desk& d1, desk& d2) 116 117 desk d(0); 118 d.price = d1.price + d2.price; 119 return d; 120 121 122 void process() 123 124 desk d1(3); 125 desk d2(4); 126 desk d = d1 + d2; 127 return; 128 感兴趣的同学可以汇编看一下,找一找它和普通的非友元函数有哪些区别。不过上面的代码还是让我们看出了一些端倪: a)友元函数不属于类,因为定义的时候我们发现没有desk:这样的前缀 b)友元算术符重载需要比普通的算术符重载多一个输入参数 c)友元函数在进行算术重载定义的时候需要多定义一个临时变量d,这在函数operator+()可以看出来 d)友元算术重载函数会破坏原来类地封装性 e)友元函数实际上就是全
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二四年度货物出口合同标的及出口手续
- 二零二四年度技术服务合同技术咨询服务合同04年专用
- 底薪加提成薪资制度合同(2篇)
- 二零二四年度货物采购合同(含详细技术参数与交付时间表)
- 二零二四年度电商企业软件许可合同
- 内控优化咨询合作协议
- 长期借款协议续借格式
- 建设工程施工合同(示范文本)
- 建筑钢管架劳务分包合同
- 生石灰购销意向协议
- DLT 866-2015 电流互感器和电压互感器选择及计算规程解读
- 小班数学活动《按颜色分类》课件
- 我的生涯发展展示
- 物流调度晋升述职报告
- 消防车辆与装备的使用指南
- 人教版pep五年级英语上下全册各课时教学反思
- 公司员工集资计划书
- 校车发展方案
- 急性疼痛治疗和APS服务课件
- 重症监护病房新生儿皮肤管理指南护理课件
- 入托入学儿童查验证培训资料
评论
0/150
提交评论