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

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


在算术符重载里面,“=”重载可能是最经常使用的一种。但是好多人就误以为在函数中,凡是类出现“=”的地方,那就是调用算术符重载,其实不然。为什么呢?我们可以看看下面的代码。首先,我们定义一个基本类:

class data { char* value; int number; public: explicit data(int num = 0){ if(num){ number = num; value = (char*)malloc(num); } } data(const data& d){ number = d.get_number(); value = (char*)malloc(d.get_number()); memmove(value, d.get_point(), d.get_number()); } ~data(){ if(number) free(value); } data& operator=(const data& d){ if(number) free(value); number = d.get_number(); value = (char*)malloc(d.get_number()); memmove(value, d.get_point(), d.get_number()); return *this; } int get_number() const {return number;} char* get_point() const {return value;} };

定义好了函数之后,我们就开始对这个类进行调用,同样代码如下所示:

45: data m(10); 0040108D push 0Ah 0040108F lea ecx,[ebp-14h] 00401092 call @ILT+30(data::data) (00401023) 00401097 mov dword ptr [ebp-4],0 46: data p = m; 0040109E lea eax,[ebp-14h] 004010A1 push eax 004010A2 lea ecx,[ebp-1Ch] 004010A5 call @ILT+35(data::data) (00401028) 004010AA mov byte ptr [ebp-4],1 47: p = m; 004010AE lea ecx,[ebp-14h] 004010B1 push ecx 004010B2 lea ecx,[ebp-1Ch] 004010B5 call @ILT+5(data::operator=) (0040100a) 48: } 上面共有三句话,我们逐一进行分析:

45句:定义了一个临时变量,调用data的构造函数

46句:出现了一个临时变量p,这里发现data类并没有调用算术符重载函数,而是调用了data的构造函数,根据45句所示,调用的肯定不是普通的构造函数,那么剩下的结果只能是拷贝构造函数

47句: 和46句的代码是一致的,但是此时调用的函数才是算术符重载函数

所以说,出现“=”的地方未必调用的都是算术符重载函数,也有可能是拷贝构造函数。那么什么时候是拷贝构造函数,什么时候是算术符重载函数呢?判断的标准其实很简单。如果临时变量是第一次出现,那么调用的只能是拷贝构造函数,反之如果变量已经存在,就像47句一样,那么调用的只能是算术符重载函数,但是我们这里定义的算数符重载函数有一个陷阱,不知道大家看出来没有?

我提示大家一下,这里的算术符重载需不需要判断拷贝的是不是自己呢?

void process() { data m(10); data p = m; p = p; } 这里最后一句,如果算术符可以自己拷贝给自己,代码正常编译和运行都没有问题,但是在某些情况下会出现很多意想不到的情况。大家可以跟着我的思路来:

data& operator=(const data& d){ if(this == &d) /* check whether it is self-copy action */ return *this; if(number) free(value); number = d.get_number(); value = (char*)malloc(d.get_number()); memmove(value, d.get_point(), d.get_number()); return *this; } 如果上面的代码没有判断复制的对象是不是自己,那么我们发现实际上value的数据实际上已经free掉了。那么此时重新分配内存,拷贝的数据只有天知道是什么数据。原来value指向的内存空间就存在了很大的不确定性,这就是算术符重载的陷阱。


【后记: 自此用汇编看C++系列全部结束,下面我们将开始数据结构和算法的讨论,欢迎关注】


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值