1.virtual修饰符
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修饰过的函数会先添加到虚表内,然后再添加子类的
2指针和引用
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
通常解释的是,指针是地址,引用是别名
但是其实本质都是一个东西,经过反汇编查看代码也一致
别名初始化后不可以修改是因为 别名 相当于一个 指针常量
地址作为常量是不可更改的,值可以修改