上一篇说了一般继承,也就是单继承的虚函数表,接下来说说多重继承的虚函数表:

1.无虚函数覆盖的多重继承:

代码:

#pragma once

//无覆盖,多重继承
class Base1
{
public: //三个虚函数
virtual void f() { cout << "Base1::f" << endl; }
virtual void g() { cout << "Base1::g" << endl; }
virtual void h() { cout << "Base1::h" << endl; }
}; class Base2
{
public: //三个虚函数
virtual void f() { cout << "Base2::f" << endl; }
virtual void g() { cout << "Base2::g" << endl; }
virtual void h() { cout << "Base2::h" << endl; }
}; class Base3
{
public: //三个虚函数
virtual void f() { cout << "Base3::f" << endl; }
virtual void g() { cout << "Base3::g" << endl; }
virtual void h() { cout << "Base3::h" << endl; }
}; //多重继承无覆盖
class Derive :public Base1 , public Base2 , public Base3
{
public:
virtual void f1() { cout << "Derive::f1" << endl; }
virtual void g1() { cout << "Derive::g1" << endl; }
virtual void h1() { cout << "Derive::h1" << endl; }
}; void Test()
{
Derive d;
}

调试结果:

可得:

1》每个父类都有虚表;

2》同样问题,虚表中没有体现出子类的虚函数;见真实内容:

可见子类的虚函数在按基类声明顺序的第一个基类的虚表中,且在此基类虚函数之后;

2.有虚函数覆盖的多重继承:

代码:

#pragma once

//有虚函数覆盖的多重继承
#pragma once //无覆盖,多重继承
class Base1
{
public: //三个虚函数
virtual void f() { cout << "Base1::f" << endl; }
virtual void g() { cout << "Base1::g" << endl; }
virtual void h() { cout << "Base1::h" << endl; }
}; class Base2
{
public: //三个虚函数
virtual void f() { cout << "Base2::f" << endl; }
virtual void g() { cout << "Base2::g" << endl; }
virtual void h() { cout << "Base2::h" << endl; }
}; class Base3
{
public: //三个虚函数
virtual void f() { cout << "Base3::f" << endl; }
virtual void g() { cout << "Base3::g" << endl; }
virtual void h() { cout << "Base3::h" << endl; }
}; //多重继承无覆盖
class Derive :public Base1, public Base2, public Base3
{
public:
virtual void f() { cout << "Derive::f" << endl; } //唯一一个覆盖的子类函数
virtual void g1() { cout << "Derive::g1" << endl; }
virtual void h1() { cout << "Derive::h1" << endl; }
}; void Test()
{
Derive d; Base1 *b1 = &d;
Base2 *b2 = &d;
Base3 *b3 = &d;
b1->f(); //Derive::f()
b2->f(); //Derive::f()
b3->f(); //Derive::f() b1->g(); //Base1::g()
b2->g(); //Base2::g()
b3->g(); //Base3::g() }

运行结果:

其实底层是这样的:

分析:

1》每个父类的虚表中原本存放f()函数的地方,被子类的f()函数覆盖;

2》其余不变;(意思是,还有没被用来覆盖的子类虚函数,任然在首个父类虚函数表的后边位置)

见图:

赐教!

详谈C++虚函数表那回事(多重继承关系)的更多相关文章

  1. 详谈C++虚函数表那回事(一般继承关系)

    沿途总是会出现关于C++虚函数表的问题,今天做一总结: 1.什么是虚函数表: 虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的.简称为V-Table. ...

  2. C++ 虚函数表与多态 —— 多重继承的虚函数表 & 内存布局

    多重继承的虚函数表会有两个虚表指针,分别指向两个虚函数表,如下代码中的 vptr_s_1.vptr_s_2,Son类继承自 Father 和 Mather 类,并且改写了 Father::func_1 ...

  3. C++虚函数表

    大家知道虚函数是通过一张虚函数表来实现的.在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承.覆盖的问题,其内容真是反应实际的函数.这样,在有虚函数的类的实例中,这个表分配在了这个实例的内存中 ...

  4. C++ 虚函数表 多重继承

    上次研究的是单继承的情况,这次研究多重继承下的虚函数表的排列情况. 这次A,A1,A2,B这几个类的继承关系如下图: 测试代码如下: #include<iostream> using na ...

  5. C++对象模型 多重继承与虚函数表

    一 多重继承 1) 代码: Code#include <iostream>using namespace std; class B1{public:    int x;    virtua ...

  6. [C++对象模型][8]多重继承与虚函数表

    转载: [C++对象模型][8]多重继承与虚函数表 一 多重继承 1) 代码: Code #include <iostream> using namespace std; class B1 ...

  7. C++ 虚函数表解析

    转载:陈皓 http://blog.csdn.net/haoel 前言 C++中 的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实 ...

  8. C++虚函数与虚函数表

    多态性可分为两类:静态多态和动态多态.函数重载和运算符重载实现的多态属于静态多态,动态多态性是通过虚函数实现的. 每个含有虚函数的类有一张虚函数表(vtbl),表中每一项是一个虚函数的地址, 也就是说 ...

  9. C++的虚函数表

    这里的例子全部来自陈皓的C++ 虚函数表解析,经过修改的. 编译器:g++ (Ubuntu 4.9.2-10ubuntu13) 4.9.2 环境:ubuntu 15.04  64位系统(地址占8字节) ...

随机推荐

  1. ThreadLocal原理

    ThreadLocal类可以看作是当前线程的一个局部变量,只有当前线程可以访问,因此是线程安全的. ThreadLocal内部维护了一个ThreadLocalMap类,ThreadLocalMap是一 ...

  2. [CQOI2007]余数求和

    大于k的部分直接加k 对于小于等于k的cnt个数 ans=cnt*k - Σ(k/i * i) 然后k/i在一段区间内不变,这段区间直接可以数列求和 # include <bits/stdc++ ...

  3. [BZOJ2296] [POJ Challenge] 随机种子

    Description 1tthinking除了随机算法,其他什么都不会.但是他还是可以ac很多题目,他用的是什么呢?他会选择一个好的随机种子,然后输出答案.往往他选择的一个好的种子可以有99%的概率 ...

  4. 【2016北京集训测试赛】azelso

    [吐槽] 首先当然是要orzyww啦 以及orzyxq奇妙顺推很强qwq 嗯..怎么说呢虽然说之前零零散散做了一些概d的题目但是总感觉好像并没有弄得比较明白啊..(我的妈果然蒟蒻) 这题的话可以说是难 ...

  5. 微信公众号接口配置验证URL

    /** * 审核填写的URL */ public function checkUrl(){ //获得参数 signature nonce token timestamp echostr $nonce ...

  6. 学习Javascript闭包(Closure)及几个经典面试题理解

    今天遇到一个面试题,结果让我百思不得其解.后来在查阅了各种文档后,理清了来龙去脉.让我们先来看看这道题: function Foo( ){ var i = 0; return function( ){ ...

  7. c#抽取pdf文档标题(2)

    public class IETitle { public static List<WordInfo> WordsInfo = new List<WordInfo>(); pr ...

  8. [解决]Linux Tomcat启动慢--Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [236,325] milliseconds

    一.背景 今天部署项目到tomcat,执行./startup.sh命令之后,访问项目迟迟加载不出来,查看日志又没报错(其实是我粗心了,当时tomcat日志还没打印完),一开始怀疑是阿里云主机出现问题, ...

  9. createjs绘制扇形的方法

    扇形由三段线条组成,两条直线和一条弧线,直线可以用createjs中的lineTo函数画出,弧线用Graphics.arc函数来画. 一.关于createjs中的Graphics.Arc API Gr ...

  10. npm打包前端项目太慢问题分析以及暂时解决方案

    npm build 打包前端项目实际上是执行 node build/build.js,但是随着项目的依赖包越来越多,项目打包时间不断延长,为了改善这个问题,需要从node入手 暂时解决方案:扩大nod ...