zoukankan      html  css  js  c++  java
  • 【C++】虚函数表vtable理解

    相关知识点

    • 二级指针

    • 不同指针类型的解引用

    • 指针类型转换

    • 对象中的虚函数与成员函数

    二级指针

    如果一个内存段存储的是一个指针,则指向该内存段的指针至少是一个二级指针。及若*p为地址,则p至少是一个二级指针。而*p为非地址,则p为一级指针。

    不同类型指针的解引用

    p为int型指针,则*p解引用的地址长度范围为4个字节;而如果p为一个对象b的指针,则*p解引用的地址长度范围为sizeof(b)

    指针类型的转换

    如果b为一个对象,则(int*)(&b)将对象指针类型转换为int型指针;(int**)*(int*)(&b)将b中的前四个字节转换为int型二级指针。

    对象中的成员函数与虚函数

    成员函数不占用内存空间,而虚函数会占用对象内存起始的4个字节,用以保持虚函数表的起始地址。

    虚函数表的遍历

    多态的虚函数动态调用体现在在调用虚函数前会先对虚函数表进行遍历来确定需要调用的函数。

    子类对虚函数的覆写

    子类如果对父类的虚函数覆写,则虚函数表中的相应函数地址会被覆盖为子类的虚函数地址;
    在这里插入图片描述

    程序示例

    include <iostream>
    using namespace std;
    class B{
    public:
    virtual void f(){cout<<"i am f();}
    virtual void g(){}
    virtual void h(){}
    
    private:
    int a;
    int b;
    int c;
    };
    
    typedef void (*pdef)(void);
    
    int main{
    B b;
    cout<<"对象b的起始地址"<<&b<<endl;
    cout<<"对象b的虚函数表表头地址"<<(int**)*(int*)(&b)<<endl;
    cout<<"虚函数表的第0个函数f()的地址"<<*((int**)*(int*)(&b)+0)<<endl;
    cout<<"虚函数表的第1个函数g()的地址"<<*((int**)*(int*)(&b)+1)<<endl;
    cout<<<<"虚函数表的第2个函数h()的地址"<<*((int**)*(int*)(&b)+2)<<endl;
    
    pdef p = (pdef)*((int**)*(int*)(&b)+0);
    p();//调用b.f()
    }
    
    • 下图p为虚函数表的表头地址,由下图可以看出*(p+0)为第一个虚函数的地址。
      二级指针p
  • 相关阅读:
    Android Studio 开发
    Jsp编写的页面如何适应手机浏览器页面
    电影
    Oracle 拆分列为多行 Splitting string into multiple rows in Oracle
    sql server 2008 自动备份
    WINGIDE 激活失败
    python安装 错误 “User installations are disabled via policy on the machine”
    ble编程-外设发送数据到中心
    iOS开发-NSString去掉所有换行及空格
    ios9 字符串与UTF-8 互相转换
  • 原文地址:https://www.cnblogs.com/bitbitbyte/p/12536625.html
Copyright © 2011-2022 走看看