详谈C++虚函数表那回事(多重继承关系)
上一篇说了一般继承,也就是单继承的虚函数表,接下来说说多重继承的虚函数表:
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++虚函数表那回事(多重继承关系)的更多相关文章
- 详谈C++虚函数表那回事(一般继承关系)
沿途总是会出现关于C++虚函数表的问题,今天做一总结: 1.什么是虚函数表: 虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的.简称为V-Table. ...
- C++ 虚函数表与多态 —— 多重继承的虚函数表 & 内存布局
多重继承的虚函数表会有两个虚表指针,分别指向两个虚函数表,如下代码中的 vptr_s_1.vptr_s_2,Son类继承自 Father 和 Mather 类,并且改写了 Father::func_1 ...
- C++虚函数表
大家知道虚函数是通过一张虚函数表来实现的.在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承.覆盖的问题,其内容真是反应实际的函数.这样,在有虚函数的类的实例中,这个表分配在了这个实例的内存中 ...
- C++ 虚函数表 多重继承
上次研究的是单继承的情况,这次研究多重继承下的虚函数表的排列情况. 这次A,A1,A2,B这几个类的继承关系如下图: 测试代码如下: #include<iostream> using na ...
- C++对象模型 多重继承与虚函数表
一 多重继承 1) 代码: Code#include <iostream>using namespace std; class B1{public: int x; virtua ...
- [C++对象模型][8]多重继承与虚函数表
转载: [C++对象模型][8]多重继承与虚函数表 一 多重继承 1) 代码: Code #include <iostream> using namespace std; class B1 ...
- C++ 虚函数表解析
转载:陈皓 http://blog.csdn.net/haoel 前言 C++中 的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实 ...
- C++虚函数与虚函数表
多态性可分为两类:静态多态和动态多态.函数重载和运算符重载实现的多态属于静态多态,动态多态性是通过虚函数实现的. 每个含有虚函数的类有一张虚函数表(vtbl),表中每一项是一个虚函数的地址, 也就是说 ...
- C++的虚函数表
这里的例子全部来自陈皓的C++ 虚函数表解析,经过修改的. 编译器:g++ (Ubuntu 4.9.2-10ubuntu13) 4.9.2 环境:ubuntu 15.04 64位系统(地址占8字节) ...
随机推荐
- Python Web-第六周-JSON and the REST Architecture(Using Python to Access Web Data)
1.JavaScript Object Notation JSON 1.JSON 官方介绍 http://www.json.org/json-zh.html 2.json1.py import jso ...
- jquery 记住账号 记住密码
<body> <label><input type="checkbox" onclick="loginBtn_user()" /& ...
- 八年架构师大咖首次揭秘,年薪50W秘籍!
序言 我是土生土长的老北京人,你们肯定觉得我很有钱,为啥呢? 因为觉得我是北京户口,其实你们错了,我的房子是靠我自己买的,父母基本上没帮到我什么,当然,我也不需要吧! 我只想说,作为一名程序员,我很自 ...
- Redis之PHP操作
一.Redis连接与认证 //连接参数:ip.端口.连接超时时间,连接成功返回true,否则返回false $ret = $redis->connect('127.0.0.1', 6379, 3 ...
- nodejs辅助前台开发系列(1) 搭建简单HTML开发环境
搭建简单的html开发环境一般需要解决两个问题: 文本编辑器 WebServer集成 在文本编辑器选择上,VS Code 无疑是一匹黑马,谁用谁知道.WebServer集成nodejs对前端来说最为友 ...
- C# Redis实战(二)
二.Redis服务 在C# Redis实战(一)中我将所有文件拷贝到了D盘redis文件夹下,其中redis-server.exe即为其服务端程序,双击即开始运行,如图 可以 ...
- 分布式日志收集系统:Flume
Flume知识点: Event 是一行一行的数据 1.flume是分布式的日志收集系统,把收集来的数据传送到目的地去. 2.flume里面有个核心概念,叫做agent.agent是一个java进程,运 ...
- 产生AJAX跨域问题的原因
1.浏览器限制 浏览器出于安全的角度,当产生跨域,则浏览器会对请求进行一些校验,校验不通过,则报跨域安全问题 2.跨域指发出去的请求不是本域的,协议.域名.端口任何一项不一样就认为是跨域 3.XHR( ...
- Oracle GoldenGate实现数据库同步
前言:最近刚好在弄数据库同步,网上查了些资料再加上自己整理了一些,做个分享! 一.GoldenGate的安装 1.安装包准备 数据库版本:Oracle Database 11g Release 2(1 ...
- 怎么用secureCRT连接Linux
首先要安装linux,参看:http://www.cnblogs.com/shenjieblog/p/5061282.html 然后要安装secureCRT,参看:http://www.cnblogs ...