<四>虚函数 静态绑定 动态绑定


代码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