虚函数原理解析

虚函数原理

虚函数的一般实现模型:每个类有一个虚函数表,内含该类中有作用的虚函数地址。每个 对象有一个vptr(虚函数表指针)指向虚函数表


如下Person类

class Person
{
public:
    virtual ~Person();
    virtual string& getName();
    virtual string& setName();   
protected:
    string name_;
};

在Person的对象Jack,有两个东西,一个是数据成员name_,一个是_Vptr_Person(指向虚函数表的指针),其中_Vptr_Person存储着以下东西:

      

如果Man集成class Person,Man如下所示:

class Man:Person
{
public:
    ~Man();
    string& getName();
    
protected:
    string hasWhat_;       //有什么呢  哈哈
    
};
在Man对象Star中有三个东西,一个是从Person中继承而来的name_,一个是自己的hasWhat,都是数据成员,另一个为_Vptr_Man(虚函数表指针):

      

其中,如果Man类里面重写了Person类里面的虚函数,则虚函数表被重写函数的对应位置替换为派生类里面的函数地址,如Man的虚函数表中,将Person::~Person() Person::getName();的地址替换为Man::~Man() 和Man::getName(),没有重写的则依旧为基类虚函数的地址


而且,此时,Man类可作为基类,继续被继承,满足如上关系。



若派生类继承多个具有虚函数的类,因为需要向上类型转换,所以派生类里面就有多个虚函数指针。则其结构体大小会增加一个虚函数指针的大小,如下代码所示:

class A
{
    virtual void f()
    {

    }
};

class B
{
    virtual void g();
};

class C:public B
{

};

class D:public B,public A
{

};

int main ()
{
    cout<<sizeof(A)<<endl;//A中没有成员变量,只有一个虚函数表指针
    cout<<sizeof(B)<<endl;//同A
    cout<<sizeof(C)<<endl;//继承了B  有一个虚函数表指针
    cout<<sizeof(D)<<endl;//继承了A 和 B,有两个虚函数表指针
    return 0;
}

具体输出依赖于机器,但是满足 sizeof(A) = sizeof(B) = sizeof(C) = sizeof(D) / 2;


   注意:虚函数指针在类中的位置,取决于编译器具体实现,不过一般虚函数表指针的位置在类的首部,即类最开始的位置。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值