zoukankan      html  css  js  c++  java
  • 多态实现之虚函数

    多态的实现分为静态多态和动态多态,静态多态主要靠函数重载,动态多态主要靠虚函数

    当类中声明了虚函数之后,该类的内存映像会获得一个虚表指针,叫做_vfptr指向该类的虚表,下面的我测试使用的类图(有的没必要的东西没有写)

    这里恰好还是一个菱形继承,但是就像我之前说的虚继承和虚表关系不大,所以单继承也是可以测试的

    其中高亮的部分就是虚表指针,用内存窗口就可以看到虚表中存放的东西了,每一个多态类的对象都有一个自己的虚表指针,并且多继承的对象会有多个_vptr指针

    m和m1的_vptr指向同一个虚表

    多继承对象有更多的_vfptr指向不同的虚表

    这里我们虽然看到的是_vfptr是放在m对象的最后,但是在内存中_vfptr是存放在m内存空间一开头的地方!!如果我们想要强取虚表并且把虚表中的函数指针打印出来看看的话,只要取m的地址(就是一开始的头地址)就可以了,=(虽然一般人不会这么做,如果只是想看看的话),如果还想打印其他的虚表的话就把指针偏移一下,_vfptr就是指向虚表的指针,就相当于指向一个函数指针数组的第一个元素指针,获得了这个指针之后就可以像访问数组一样访问这个虚表了

    如下图所示对象m地址空间一开始就是虚表指针_vfptr,紧接着是虚继承表指针_vbptr(要区分开!)(虚继承表详解看菱形继承那篇博客)

    强取虚表打印代码

     1 void PrintVtable(int *vTable)
     2 {
     3     for (int i = 0; vTable[i] != 0; i++)
     4     {
     5         printf("%x
    ", vTable[i]);
     6         FUNC f = (FUNC)vTable[i];
     7         f();
     8     }
     9 }//因为指针和int型变量都是4个字节,所以我们用整型变量来存放地址
    10 
    11 
    12 
    13 
    14 int *vTable = (int *)(*(int *)&m);
    15 PrintVtable(vTable);
  • 相关阅读:
    jQuery上传插件Uploadify使用详解
    SQL之case when then用法
    myeclipse 上安装 Maven
    ps 简介
    Linux 查看进程和删除进程
    EL表达<%@page isELIgnored="false"%>问题
    刷新本地的DNS缓存
    IDEA中 @override报错的处理步骤
    Caused by: org.springframework.core.NestedIOException: ASM ClassReader failed to parse class file
    jsp中${param.user}不解析,原样输出。
  • 原文地址:https://www.cnblogs.com/lenomirei/p/5516235.html
Copyright © 2011-2022 走看看