用汇编的眼光看C++(之算术符重载) (一)

2014-11-24 12:43:50 · 作者: · 浏览: 5

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

算术符重载是类的有一个特性,但是每个人使用的方法不一样。用的好,则事半功倍;但是如果不正确的使用,则会后患无穷。

(1) 简单算术符介绍

那什么是算术符重载呢?我们可以举个例子。一般来说,我们定义两个int类型的变量的话,我们就可应对这两个类型进行加、减、乘、除的操作,同时还能比较判断、打印、数组操作、*号操作等等。那么如果我们想自己定义的类也具有这样的属性,那我们应该怎么办呢?当然就要算术符重载了。首先,我们对基本class做一个定义:

class desk

{

public:

int price;

desk(int value):price(value) {}

~desk() {}

desk& operator+= (desk& d){

this->price += d.price;

return *this;

}

};

class desk

{

public:

int price;

desk(int value):price(value) {}

~desk() {}

desk& operator+= (desk& d){

this->price += d.price;

return *this;

}

};

下面,可以用一个范例函数说明一下使用的方法:

74: desk n(5);

0040126D push 5

0040126F lea ecx,[ebp-10h]

00401272 call @ILT+0(desk::desk) (00401005)

00401277 mov dword ptr [ebp-4],0

75: desk m(10);

0040127E push 0Ah

00401280 lea ecx,[ebp-14h]

00401283 call @ILT+0(desk::desk) (00401005)

00401288 mov byte ptr [ebp-4],1

76: n += m;

0040128C lea eax,[ebp-14h]

0040128F push eax

00401290 lea ecx,[ebp-10h]

00401293 call @ILT+40(desk::operator+=) (0040102d)

77: }

74: desk n(5);

0040126D push 5

0040126F lea ecx,[ebp-10h]

00401272 call @ILT+0(desk::desk) (00401005)

00401277 mov dword ptr [ebp-4],0

75: desk m(10);

0040127E push 0Ah

00401280 lea ecx,[ebp-14h]

00401283 call @ILT+0(desk::desk) (00401005)

00401288 mov byte ptr [ebp-4],1

76: n += m;

0040128C lea eax,[ebp-14h]

0040128F push eax

00401290 lea ecx,[ebp-10h]

00401293 call @ILT+40(desk::operator+=) (0040102d)

77: }

大家可以把重点放在76句上面,不过74、75句我们也会稍微介绍一下:

74句: 创建desk类型的临时变量n,调用构造函数

75句: 创建desk类型的临时变量m,调用构造函数

76句: 两个desk类型的数据相加,但是在汇编的形式上面,我们发现编译器把这段代码解释成函数调用,也就是我们在上面定义的算术符重载函数。

(2)new、free重载

C++里面,我们不光可以对普通的算术符进行重载处理,还能对new、free进行重载。通过重载new、free,我们还可以加深对代码的认识,正确认识构造、析构、堆内存分配的原理。

首先,我们对new和delete进行重载定义:

class desk

{

public:

int price;

desk(int value):price(value) {}

~desk() {}

void* operator new(size_t size) {return malloc(size);}

void operator delete (void* pData) { if(NULL != pData) free(pData);}

};

class desk

{

public:

int price;

desk(int value):price(value) {}

~desk() {}

void* operator new(size_t size) {return malloc(size);}

void operator delete (void* pData) { if(NULL != pData) free(pData);}

}; 那么使用呢?

72: desk* d = new desk(10);

0040127D push 4

0040127F call @ILT+65(desk::operator new) (00401046)

00401284 add esp,4

00401287 mov dword ptr [ebp-18h],eax

0040128A mov dword ptr [ebp-4],0

00401291 cmp dword ptr [ebp-18h],0

00401295 je process+56h (004012a6)

00401297 push 0Ah

00401299 mov ecx,dword ptr [ebp-18h]

0040129C call @ILT+5(desk::desk) (0040100a)

004012A1 mov dword ptr [ebp-24h],eax

004012A4 jmp process+5Dh