博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
虚表思考-再探虚表布局
阅读量:5168 次
发布时间:2019-06-13

本文共 1917 字,大约阅读时间需要 6 分钟。

 

思考类的布局,以前一直以为 一个类可能有多个虚表。
今天下午特别的写程序测试下。

 

程序参考了:陈皓博客的

结论是:无论一个类怎么继承来的,他的虚表只有一个!//

 

感觉:注意:虚表的理解,至少2个层次,动静结合

静,要知道 类的布局
动,要知道函数 动态绑定

 

 

 

#include "stdafx.h"

 

 

#include <iostream>

 

using namespace std;

 

 

 

class Base{

 

 

//private:

 

public:

 

  //virtual  ~Base()

 

  //{cout<<"i am in dtor"<<endl;//只有显示申明后才object中显示

  //}

 

 

public:

 

  virtual void f() { cout << "Base::f" << endl; }

 

  virtual void g() { cout << "Base::g" << endl; }

 

  void h() { cout << "unvirtual Base::h" << endl; }

 

 

};

 

 

class derived:public Base{

 

 

 

public:

 

  //virtual void f() { cout << "derived::f" << endl; } //使用父亲的

  virtual void g() { cout << "derived::g" << endl; }

 

 

  void h() { cout << "unvirtual derived::h" << endl; }

 

  virtual void i() { cout << "his own derived::i" << endl; }

 

 

};

 

 

void test_Main(){

 

  typedef void(*Fun)(void);

 

 

  Base b;

 

 

  Fun pFun = NULL;

 

 

  cout << "vtbl address" << (int*)(&b) << endl;

 

  cout << "vtbl 1st function" << (int*)*(int*)(&b) << endl;

 

  cout<<"打印转换过程"<<&b<<" "<<(int*)(&b)<<" "<<*(int*)(&b)<<" "<<(int*)*(int*)(&b)<<endl;

 

  cout<<"在此打印地址+ "<<&b+1<<" "<<(int*)(&b)+1<<" "<<*(int*)(&b)+1<<" "<<(int*)*(int*)(&b) +1<<endl;

 

 

 

  // Invoke the first virtual function

 

  pFun = (Fun)*((int*)*(int*)(&b));

 

 

 

  ( (Fun)*((int*)*(int*)(&b)) )();

 

     //奇怪的bug:显示的dtor,就要这里报错//这里就注释了base dtor

 

     //( (Fun)*((int*)*(&b)) )();//无法从Base转换为int *

 

     //( (Fun)*(*(int*)(&b)) )();//error C2100: 非法的间接寻址

     //( *((int*)*(int*)(&b)) )(); //error C2064: 项不会计算为接受0 个参数的函数

                   //不强制转换报错!不知道返回类型,不知道参数。所以转换

 

 

 

  pFun();

 

 

  (Fun)*((int*)*(int*)(&b)+0);  // Base::f()

 

  pFun();

 

 

  pFun=(Fun)*((int*)*(int*)(&b)+1);  // Base::g()

 

  pFun();

 

 

  //pFun=(Fun)*((int*)*(int*)(&b)+2);  // Base::h() //不存在vtbl..用户可以自己调用析构?

  //pFun();

 

 

 

 

  derived d;

 

 

 

      (  (Fun)* (int *)*(int *)(&d) ) ();//调用保留的函数

         // (Fun)* (int *)*(int *)(&d)  (); //结合性会计算为接受0 个参数的函数

    ( (Fun)* ( (int *)*(int *)(&d) +1) )();//调用重写

 

    ( (Fun)* ( (int *)*(int *)(&d) +2) )(); //调用新的虚函数

 

 

 

}

 

//调试方法:就是调用

test_Main()

 

后面试我的测试截图:

 

 

 

 

 补上虚表转换图示:

 

 

 

 

转载于:https://www.cnblogs.com/titer1/archive/2012/08/02/2620452.html

你可能感兴趣的文章
setImageBitmap和setImageResource
查看>>
springMVC4 注解配置实例
查看>>
单片机编程
查看>>
Filter in Servlet
查看>>
Linux--SquashFS
查看>>
Application Pool Identities
查看>>
2017-3-24 开通博客园
查看>>
【MySQL性能优化】MySQL常见SQL错误用法
查看>>
Vue2全家桶之一:vue-cli(vue脚手架)超详细教程
查看>>
Struts 2 常用技术
查看>>
树形DP
查看>>
python flask解决上传下载的问题
查看>>
语法测试
查看>>
CES1
查看>>
CES2
查看>>
文件方式实现完整的英文词频统计实例
查看>>
ListControl的用法
查看>>
单个SWF文件loading加载详解(转)
查看>>
SQLServer中的CTE通用表表达式
查看>>
linux第1天 fork exec 守护进程
查看>>