图解虚函数笔记

虚函数笔记

基类指针(或函数)调用派生类中与基类同名函数时,它只能看到基类的函数,

看下面函数:

class A {
    
    
public:
    
    
       virtual void fun0() { cout << "A::fun0" << endl; }
    
    
       int a;
    
    
       int b;
    
    
};
    
    
int main(int argc, char* argv[])
    
    
{
    
    
       A  a;
    
    
       cout << "Size of A = " << sizeof(a) << endl;
    
    
              return 0;
    
    
}      
    
    

结果如下:Size of A = 12 其虚函数在内存中结构是这样的:

如果有两个虚函数时VPTR指针如下:

 

再看下面的程序:

class A {
    
    
public:
    
    
       virtual void f() { }
    
    
};
    
    
class B {
    
    
public:
    
    
       virtual void f() { }
    
    
};
    
    
class C {
    
    
public:
    
    
       virtual void f() { }
    
    
};
    
    
class Drive : public A, public B, public C {
    
    
};
    
    
int main() {
    
    
       Drive d;
    
    
       cout << "Size is = " << sizeof(d) << endl;
    
    
       return 0;
    
    
}      
    
    

结果如下:Size is = 12 ,我们可以看看它的内存结构图:

 

虚函数可以实现函数的多态性,多态性是指用一个名字定义不同的函数,这函数执行不同但又类似的操作,从而实现“一个接口,多种方法”。C++程序在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。
   
#include <iostream.h >
    
    
 class shape{
    
    
  public:
    
    
    virtual void draw(){cout<<"shape::draw()"<<endl;}
    
    
    virtual void area(){cout<<"shape::area()"<<endl;}
    
    
    void fun(){draw();area();}
    
    
 };
    
    
 class circle:public shape{
    
    
  public:
    
    
    void draw(){cout<<"circle::draw()"<<endl;}
    
    
    void adjust(){cout<<"circle::adjust()"<<endl;}
    
    
 };
    
    
 main(){
    
    
    shape oneshape;
    
    
    oneshape.fun();
    
    
    
    
    
    circle  circleshape;
    
    
    shape&  baseshape=circleshape;
    
    
    baseshape.fun();
    
    
}
  
  

   
    
  
  
在上面的程序中,this指针不同,从而连接到不同的fun函数。那么C++如何编译这些指令呢。道理在于:所有的基类的派生类的虚拟函数表的顺序与基类的顺序是一样的,对于基类中不存在方法再按照声明次序进行排放。这样不管是shape还是circle或者从shape又继承出来的其余的类它们的虚拟函数表的第一项总是draw函数的地址,然后是area的地址。对于circle类,下面的才是adjust的地址。因此不管对于shape还是circlethis->draw总是编译成 call this->VTABLE[0]; this->area()总是翻译成 call this->VTABLE[1]; 程序到真正运行时候将会发现this的真正指向的对象,如果是shape,则调用shape->VTABLE[0],如果是circle,则调用circle->VTABLE[1],如下图:
   
   

参考:
1. Zeeshan Amjad
写的"ATL on the Hood”

2. 解析动态联()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值