C++基础之验证虚表的存在(十九)

#include <iostream>
#include <stdio.h>
using std::endl;
using std::cout;

class Base
{
private:
    int _ia;

public:
    Base(int a)
    :_ia(a)
    {
        cout<<"Base(int a)"<<endl;
    }
    virtual
    void print()
    {
        cout<<"Base::_ia = "<<_ia<<endl;
    }

};

class Derived
:public Base
{
private:
    int _ib;

public:
    Derived(int a,int b)
    :Base(a)
    ,_ib(b)
    {
        cout<<"Derived(int a,int b)"<<endl;
    }

    void print() 
    {
        cout<<"Derived::_ib = "<<_ib<<endl;
    }

};

int main()
{
    Derived derived(2,3);
    cout<<"&derived = "<<&derived<<endl;
    cout<<"derived对象地址(long*)&derived = "<<(long*)&derived<<endl;  //内存布局中的第一个指针
    cout<<"虚表地址*(long*)&derived = "<<(long*)*(long*)&derived<<endl;
    derived.print();
    cout<<"int ia = (int)*((long*)&derived+1) = "<<(int)*((long*)&derived+1)<<endl;
    cout<<"int ib = (int)*((int*)&derived+3) = "<<(int)*((int*)&derived+3)<<endl;

    cout<<sizeof(derived)<<endl;
    printf("第一个虚函数入口地址 = %p\n",(long*)*(long*)*(long*)&derived);
    typedef void (*pfunc)(void);
    pfunc p=(pfunc)*(long*)*(long*)&derived;
    p();
    printf("第一个虚函数入口地址 = %p\n",p);
}

通过内存布局我们可以知道在普通继承时,派生类Derived继承Base时虚表位于前8个字节,然后是Base的数据成员其次是派生类的数据成员。通过这个特性我们可以通过指针访问对象中的任意一个数据成员和虚表中的函数。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值