<四>虚函数 静态绑定 动态绑定
代码1
class Base
{
public:
Base(int data=10):ma(data){
cout<<"Base()"<show(); //静态绑定(编译期间绑定)
pb->show(100) //静态绑定(编译期间绑定)
cout<
代码2
class Base
{
public:
Base(int data=10):ma(data){
cout<<"Base()"<show(); //动态绑定(运行期间绑定)
pb->show(100) //动态绑定(运行期间绑定) )
cout<
在上面代码2中,Base 中void show()和 void show(int) 为虚函数, 在Derive 中有返回值,函数名,参数列表都
相同的 show()方法,这个时候 我叫 重写(或覆盖 即要返回值,函数名,参数列表 都相同),这个Derive中的void show()方法也会处理成虚函数.所以有
下图 Derive中的show()方法地址替换掉继承来的Base的show()函数地址 ,同时我们也可以看到Base中的 void show(int) 并没有被覆盖
覆盖:基类和派生类的方法,返回值,函数名以及参数列表都相同,而且基类的方法是虚函数,那么派生类的方法就自动处理成虚函数,他们之前成为覆盖关系.
所以根据上图,我们说 覆盖 其实是指虚函数表中函数地址的覆盖
代码2中的这段代码
Base *pb=&d;
pb->show(); //动态绑定(运行期间绑定)
pb->show(100) //动态绑定(运行期间绑定) )
pb->show() pb是Base类型,所以编译器会去Base中查看void show()函数情况
如果是普通函数,那么静态绑定(编译期绑定),但是发现是 void show()函数是个虚函数就进行动态绑定了
同理 pb->show(100)发现Base中的void show(int )也是个虚函数,所以执行动态绑定(运行期绑定).
但是 这两个函数在Derive虚函数表中的区别就是,void show()被Derive覆盖掉了,即虚函数表中的地址被覆盖了
而void show(int) 为被覆盖,所以虚函数表中的 地址仍然是Base的void show(int)的地址
----------------------------------------
cout<d(vfptr)->Derive vftable -> Class Derive