用汇编的眼光看C++(之指针)

发表于:2012-5-15 09:35  作者:feixiaoxing   来源:51Testing软件测试网采编

字体: | 上一篇 | 下一篇 |我要投稿 | 推荐标签:

  我们既可以把节点NODE的地址看是NODE*,也可以堪称是NODE**,两者之间有差别吗?(其实没有区别)

  linux 内核代码上面有一种计算偏移值的方法,大家可以参考一下:

int offset = (int)&(((NODE*)(0))->next);

  (6)class指针

  class指针比较复杂,不过大家可以从一个小范例看出一些端倪:

class fruit
{
public:
 fruit() {}
 ~fruit() {}
 void print() {printf("fruit!\n");}
};

class apple : public fruit
{
public:
 apple() {}
 ~apple() {}
 void print() {printf("apple!\n");}
};

void process()
{
 fruit f;
 apple* a = (apple*)&f;
 a->print();
 fruit* b = &f;
 b->print();
}

  熟悉C++的朋友可以很快知道这道题目的答案了,那么为什么a和b都指向同一个地址,使用了相同的print函数,但是结果不同。我想这主要是因为两者数据类型不同的缘故。一旦指针和某一种数据类型绑在了一起,那么这个指针的所有行为事实上都已经被这种类型的数据所限定了。普通数据类型是这样,自定义的class类型也是这样。只要不是在print函数前面加上virtual,我们就会发现两个print的调用都是硬编码,和普通的函数调用无异。所以说,指针离不开数据类型,离开具体类型的地址是没有意义的。就像void*是可以原谅的,但是void却是万万不能接受的。下面的汇编代码很好的说明了这一点。

65:       fruit f;
0040132D   lea         ecx,[ebp-10h]
00401330   call        @ILT+35(fruit::fruit) (00401028)
00401335   mov         dword ptr [ebp-4],0
66:       apple* a = (apple*)&f;
0040133C   lea         eax,[ebp-10h]
0040133F   mov         dword ptr [ebp-14h],eax
67:       a->print();
00401342   mov         ecx,dword ptr [ebp-14h]
00401345   call        @ILT+0(apple::print) (00401005)
68:       fruit* b = &f;
0040134A   lea         ecx,[ebp-10h]
0040134D   mov         dword ptr [ebp-18h],ecx
69:       b->print();
00401350   mov         ecx,dword ptr [ebp-18h]
00401353   call        @ILT+25(fruit::print) (0040101e)

  (全文完)

  【预告: 下面一篇博客主要讨论汇编语言和流程控制】

相关链接:

用汇编的眼光看C++(开篇)

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


33/3<123

评 论

论坛新帖



建议使用IE 6.0以上浏览器,800×600以上分辨率,法律顾问:上海信义律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2021, 沪ICP备05003035号
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪公网安备 31010102002173号

51Testing官方微信

51Testing官方微博

扫一扫 测试知识全知道