【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱: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++系列全部结束,下面我们将开始数据结构和算法的讨论,欢迎关注】

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

  1. 用汇编的眼光看C++(之 总结篇)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 早在八月份的时候,就陆陆续续写了二十多篇用汇编语言看C++的博客内容.在此为了做一个概括,也为 ...

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

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 算术符重载是类的有一个特性,但是每个人使用的方法不一样.用的好,则事半功倍:但是如果不正确的使 ...

  3. 用汇编的眼光看C++(之拷贝、赋值函数)

    拷贝构造函数和复制函数是类里面比较重要的两个函数.两者有什么区别呢?其实也很简单,我们可以举个例子,加入有这样一个类的定义: [cpp] view plaincopy class apple { pu ...

  4. 用汇编的眼光看C++(之退出流程)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 无论是在判断还是在循环的过程中,通常在遇到合适的条件的时候就会退出相应的模块.跳出模块运行的方 ...

  5. 用汇编的眼光看C++ (之x86汇编)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 说到用汇编的眼光看C++语言,那么怎么阅读汇编代码就成了我们需要解决的一个问题.其实,实话说, ...

  6. 从汇编的眼光看C++(之delete内存泄露)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 有过C语言编程的朋友大多知道,如果在malloc内存之后不及时free掉内存,那么很有可能会造 ...

  7. 用汇编的眼光看c++(之模板函数)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]  如果说模板类定义的是一种数据类型,那么模板函数定义的就是一种函数.既然是函数,那么就有输入数 ...

  8. 从汇编的眼光看C++(之泛型编程)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 泛型编程其实不难.本质上说,泛型编程就是让通用的算法应用到所有的数据类型.具体来说,int是我 ...

  9. 用汇编的眼光看C++(之判断流程)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 在我们平常的编程当中,用于判断的地方很多,但主要有下面三种方式:if-else:switch: ...

最新文章

  1. linux跨主机复制文件
  2. 能和LoadRunner匹敌的VS2010/2012Web负载测试
  3. Supervisor 托管服务
  4. android 获取网卡mac_Android获取本机Mac地址及IP地址方法
  5. Elasticsearch技术解析与实战(六)Elasticsearch并发
  6. C程序的储存空间是如何分配?
  7. 做好这5点基本要求 才能算一个合格的HTML5动画
  8. 为什么数据库表字段要限制长度?
  9. Python资源下载
  10. 蓝桥杯历届真题题目+解析+代码+答案(2013-2020)(JavaA、B、C组)(C++语言)(Python)
  11. iOS WKWebView 设置默认系统字体
  12. input 标签的属性class是什么作用?
  13. java.lang.Byte常用方法
  14. 2.模仿小米通讯录的快速索引demo
  15. 电脑微信关闭自动保存_微信自动保存图片怎么关闭
  16. 【翻译】Unity2017.2.0f3 版本发布说明
  17. 与领导争论问题的技巧[zt]
  18. 芯盾时代:一种会思考的新一代安全身份认证方式
  19. anki卡片浏览器_Anki Guide by Corkine
  20. 二维计算机动画基础,二维计算机动画制作新技术分析

热门文章

  1. requests 证书验证
  2. 英国政府将设立10亿英镑光网基金
  3. 别在最吃苦的年龄选择了潇洒
  4. VS2010给Activex添加接口
  5. Error:(1, 1) java: 非法字符: ‘\ufeff’
  6. MVC源码分析 - 路由匹配
  7. spring 第一篇(1-3):鸟瞰spring蓝图
  8. centos6 下用yum 安装 nginx
  9. C#里如何遍历枚举所有的项
  10. C# WinForm 文件上传下载