c++中的虚指针和虚表


这是侯捷老师上课所用的ppt,右边类A,B,C三个类的继承关系,继承关系包含两层意思,一层是父类和子类的内存模型,从ppt的左边可以看的很清楚,第一个成员是一个地址,也就是虚指针,当一个类中有虚函数的时候,对象中就会有一个虚指针,子类会拥有父子的成员变量,另一层就是函数,继承关系继承的函数的调用权。ppt中间是虚函数表,每一个类中都有一个虚函数表,里面存的都是虚函数的地址,当对象要调用虚函数是就会去查虚函数表,通过虚函数表里面相应的地址去访问对应的虚函数函数,因为当虚函数被子类override后,当个函数就是独立的,通过上面续表里面的地址也可以看出,两个函数的函数地址也是不同的。上面的图画的非常清楚,编译的时候是这样编译的,而运行的时候调用是通过(*(p->vptr)[n])(p)或者(*p->vptr[n])(p)来调用的,p是对象,加粗的是第一步,取到对应函数的地址,后面的就是通过函数指针的方式调用对应的虚函数。第二种调用的括号能后去掉是因为操作符的优先级决定的。

c++操作符的优先级:

关于公有继承和私有继承和保护继承的区别可以参考博客:
https://www.cnblogs.com/muyi23333/articles/13527614.html

接下来演示一个实际的例子:

#include <iostream>
using namespace std;
class A
{public:virtual void foo(){cout << "A's foo()" << endl;bar();}virtual void bar(){cout << "A's bar()" << endl;}
};class B : public A
{public:void foo(){cout << "B's foo()" << endl;A::foo();}void bar(){cout << "B's bar()" << endl;}
};int main()
{B bobj;A*aptr = &bobj;aptr->foo();A aobj = *aptr;aobj.foo();
}

//这个明白,多态性
A’s foo()//这个也明白,执行A::foo();
B’s bar()//虽然调用的是这个函数:A::foo(); 但隐式传入的还是bobj 的地址(bar()的前面有个this指针) , 所以再次调用bar();调用时还是会调用B的函数, 与虚函数指针有关
aobj.foo()输出结果是:
A’s foo() //这个不是指针,aobj完全是一个A的对象,与多态没有关系
B’s bar()

通过上一个例子可以看出只有通过指针调用的时候才会触发多态机制,通过对象是无法触发多态机制的。

#include <iostream>
using namespace std;
class Base1
{public:Base1(){b1 = 0;}virtual void func1() { cout << "B1:func1" << endl; }virtual void func2() { cout << "B1:func2" << endl; }
private:int b1;
};
class Base2
{public:Base2(){b2 = 0;}virtual void func1() { cout << "B2:func1" << endl; }virtual void func2() { cout << "B2:func2" << endl; }
private:int b2;
};
class Derive :public Base1, public Base2
{public:Derive(){d = 0;}virtual void func1() { cout << "D:func1" << endl; }virtual void func3() { cout << "D:func3" << endl; }
private:int d;
};
int main()
{Derive d;cout << (void*)(*((int*)*((int*)(&d)))) << endl;cout << (void*)(*((int*)*((int*)(&d) + sizeof(Base1) / 4))) << endl;int a = 0;cin >> a;return 0;
}



上面演示的是多继承时虚函数表和虚指针的状态,假设父类都有虚函数的话,有几个父类就有几个虚指针,有几个虚函数表,虚指针的首地址就是对象的首地址,然后就是指针偏移了,基本功。
sizeof(d)的大小居然是20,父类的成员无论是不是private都会在子类的对象空间中构造,只不过无法方问,记下了。

c++中的虚指针和虚表相关推荐

  1. C++中虚函数、虚指针和虚表详解

    关于虚函数的背景知识 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数. 存在虚函数的类都有一个一维的虚函数表叫做虚表.每一个类的对象都有一个指向虚表开始的虚指针.虚表是和类对应的 ...

  2. 虚函数,虚指针和虚表详解

    关于虚函数的背景知识 1. 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数. 2. 存在虚函数的类都有一个一维的虚函数表叫做虚表.每一个类的对象都有一个指向虚表开始的虚指针.虚表 ...

  3. 虚函数、虚指针和虚表

    虚函数.虚指针和虚表 http://eriol.iteye.com/blog/1167737 关于虚函数的背景知识 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数. 存在虚函数的 ...

  4. 虚指针、虚表及内存布局

    一.虚指针及虚表的概念 首先要清楚,所谓指针其实质就是一个内存地址值,形如0x12345678: 其次,要知道,函数名本身就是一个地址: 虚指针:其实就是一个地址值,以该地址为起始地址的一片内存单元存 ...

  5. 通过对象指针的方式强行指定到子类_C++中的虚指针与虚函数表

    ​ 最近在逛B站的时候发现有候捷老师的课程,如获至宝.因此,跟随他的讲解又复习了一遍关于C++的内容,收获也非常的大,对于某些模糊的概念及遗忘的内容又有了更深的认识. 以下内容是关于虚函数表.虚函数指 ...

  6. 【C++】最通俗的多态、虚表、虚指针讲解

    从C++使用者角度看多态 1 即使没有虚函数也能重写方法 多态需要两个特性: (1)方法重写(override):父类与子类具有函数签名完全相同的方法. (2)向上类型转换(upcasting):用一 ...

  7. C++虚函数的实现方式(虚表+虚指针)

    虚函数表实现原理 虚函数的实现是由两个部分组成的,虚函数指针与虚函数表. 用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数. 存在虚函数的类都有一个一维的虚函数表叫做虚表.每一个类 ...

  8. 虚函数,虚表深度剖析

    面向对象,从单一的类开始说起. class A { private:int m_a;int m_b; }; 这个类中有两个成员变量,都是int类型,所以这个类在内存中占用多大的内存空间呢? sizeo ...

  9. C++_vptr与vtbl,虚函数与虚表

    C++_vptr与vtbl,虚函数与虚表 一:虚函数表指针(vptr)创建时机 vptr跟着对象走,所以对象什么时候创建出来,vptr就什么时候创建出来,也就是运行的时候. 当程序在编译期间,编译器会 ...

最新文章

  1. 6.package配置相关
  2. Java综合知识总结_数据库篇
  3. linux6.4 vnc安装与配置,Oracle Enterprise Linux 6.4 下配置vncserver
  4. java中的操作符(位操作符>>与>>>的区别)
  5. 系统架构设计师 - 软件架构设计 - 软件架构风格
  6. Linux下 -bash: php: command not found 命令找不到
  7. 利用 Composer 一步一步构建自己的 PHP 框架(四)——使用 ORM
  8. JFinal开发8个常见问题
  9. 刷题记录 CF每日一题打卡 2020.5月?-六月16
  10. 运算放大器由来及虚短虚断的讨论
  11. Idea的JShell Console
  12. Redis java如何清除缓存 redisTemplate
  13. 数论 | 秦九韶算法(Horner法则)
  14. eclipse git 上下箭头表示什么
  15. 用python写爬虫(一)初识爬虫
  16. 四川大学计算机专业调剂,2019年四川大学计算机学院(软件学院)考研调剂信息
  17. RTP:一种实时应用的传输协议 (RFC-3550)
  18. 【听书笔记-0515】-《清单革命》
  19. unity URP内置shader lit解析
  20. 大创项目部分笔记(1)

热门文章

  1. 草图大师免费模型分享2022.03.10之草图溜溜
  2. matlab绘制世界地图(含国界)、中国地图(含省界),可下载m_map和shp文件
  3. nodemcu c语言开发,nodemcu连接到中移onenet平台
  4. 避免使用虚函数作为库的接口
  5. Python项目实战学习案例--股票模拟交易系统
  6. C++构造函数私有化作用
  7. 材料科学计算机模拟技术,计算机模拟技术在材料科学中的应用
  8. 计算机硬盘内存不足,电脑提示磁盘空间不足怎么办
  9. YII Framework学习教程-用YIIC快速创建YII应用之二-2011-11-11
  10. go语言 declared and not used