动多态(动态(晚)绑定) 虚函数在运行时确定调用方式,也叫运行时多态
用寄存器带(寄存器里存放的是什么,只有在运行期才可以得到)
静多态(静态(早)绑定) 普通函数在编译期间确定调用方式
直接call函数入口地址(普通函数编译期间函数入口地址就已经确定,放在了符号表中,而符号表不加载到内存中,运行时内存只加载数据段(.data)和指令段(.text))
调用call时做两件事情:
(1)保存着当前指令的下一条指令地址。
(2)直接跳转至目标函数。
链接过程:合并符号表---------->函数名(生成符号)对应函数入口地址
运行时不加载符号表(意味着不知道函数的入口地址),那如何拿虚函数的入口地址呢???
将数据存放在.rodata(只读数据段),通过加载器将数据加载到内存中,从而拿到虚函数入口地址
运行时多态调用机制实现???
通过对象--->找对象的虚函数表------->拿出虚函数入口地址----------->赋给寄存器------------->通过寄存器带
哪些函数可以设置为虚函数???
1、构造函数 err
2、析构函数 ok
3、static 修饰的成员方法 err
4、inline函数 err
虚函数设置条件???
1、函数能取地址
2、必须依赖对象调用 通过对象内存布局中的vfptr找vftable
动多态发生条件???
1、指针调用虚函数
2、对象必须完整(对象完整???即就是对象构造完成,有内存块及对应的属性<数据>)
int main()
{
Base base(10);
base.show();//静多态
Derive derive(20);
derive.show();//静多态
Base* pb = &base;
pb->show();//动多态
Derive* pd = &derive;
pd->show();//动多态
}
通过查看反汇编进一步确定静、动多态的产生