virtual作为C++里的虚表函数关键字
class Data { public: int x = 2; int y = 3; void add() { } virtual void Function1() { } };
1.把以上类实例名为obj的对象
2.并使用obj.add(); obj.Function1();调用函数,经过反汇编后查看的是直接寻址
//obj.add(); 00DE19E2 8D 4D EC lea ecx,[ebp-14h] 00DE19E5 E8 A8 FA FF FF call 00DE1492 //obj.Function1(); 00DE19DA 8D 4D EC lea ecx,[ebp-14h] 00DE19DD E8 AB FA FF FF call 00DE148D
3.如果定义一个Data*类型的指针来调用函数,经过反汇编查看后使用的是间接寻址,但是add依旧使用直接寻址
//nP->add(); 00DE19D2 8B 4D E0 mov ecx,dword ptr [ebp-20h] 00DE19D5 E8 B8 FA FF FF call 00DE1492 //nP->Function1(); 00DE19BD 8B 45 E0 mov eax,dword ptr [ebp-20h] 00DE19C0 8B 10 mov edx,dword ptr [eax] 00DE19C2 8B F4 mov esi,esp 00DE19C4 8B 4D E0 mov ecx,dword ptr [ebp-20h] 00DE19C7 8B 02 mov eax,dword ptr [edx] 00DE19C9 FF D0 call eax 00DE19CB 3B F4 cmp esi,esp 00DE19CD E8 DB F8 FF FF call 00DE12AD
总结:
1.不管定义多少个被virtual关键字修饰的函数,virtual的关键字都占4字节。
2.经过virtual关键字修饰以后,对象首地址中会存放一个4字节大小的虚表地址,这个地址中存放了被virtual关键字修饰过的函数地址。
3.两个类如果存在继承关系,那么父类里面被virtual修饰过的函数会先添加到虚表内,然后再添加子类的
int a = 10; int& b = a;//引用a int* c = &a;//指针a
int a = 10; 013224F3 C7 45 D4 0A 00 00 00 mov dword ptr [a],0Ah int& b = a; 013224FA 8D 45 D4 lea eax,[a] 013224FD 89 45 C8 mov dword ptr [b],eax int* c = &a; 01322500 8D 45 D4 lea eax,[a] 01322503 89 45 BC mov dword ptr [c],eax
通常解释的是,指针是地址,引用是别名
但是其实本质都是一个东西,经过反汇编查看代码也一致
别名初始化后不可以修改是因为 别名 相当于一个 指针常量
地址作为常量是不可更改的,值可以修改
int &b=a; 等于int* const b = &a;欢迎分享,转载请注明来源:内存溢出
评论列表(0条)