c++多继承多态
C++多继承多态的实现
如果一个类中存在虚函数,在声明类的对象时,编译器就会给该对象生成一个虚函数指针,该虚函数指针指向该类对应的虚函数表。
多态的实现是因为使用了一种动态绑定的机制,在编译期间不确定调用函数的地址,在调用虚函数的时候,去查询虚函数指针所指向的虚函数表。
派生类生成的对象中的虚函数指针指向的是派生类的虚函数表,因此无论是基类还是派生来调用,都是查询的是派生类的表,调用的是派生类的函数。
如果发生了多继承,多个基类中都有虚函数,那么该是怎样的呢?虚函数指针如何排列,多个基类的指针为什么能够同时指向派生类对象,同时发生多态?
请看下面这段程序
#include <stdio.h>
#include <iostream>
using namespace std;
class Base1{
public:
void fun()
{
printf("this is Base1 fun\n");
}
virtual void fun1()
{
printf("this is Base1 fun1\n");
}
};
class Base2{
public:
void fun()
{
printf("this is Base2 fun\n");
}
virtual void fun2()
{
printf("this is Base2 fun1\n");
}
};
class Derived : public Base1,public Base2{
public:
void fun()
{
printf("this is Derived fun\n");
}
void fun1()
{
printf("this is Derived fun1\n");
}
void fun2()
{
printf("this is Derived fun2\n");
}
};
int main()
{
Derived *pd = new Derived();
Base1 *p1 = (Base1 *)pd;
Base2 *p2 = (Base2 *)pd;
p1->fun();
p2->fun();
p1->fun1();
p2->fun2();
printf("Base1 p1:%x\n", p1);
printf("Base2 p2:%x\n", p2);
return 0;
}
运行结果如下
feng@mint ~/code/c++/cpp_muti_drived
$ ./muti_derived
this is Base1 fun
this is Base2 fun
this is Derived fun1
this is Derived fun2
Base1 p1:2097c20
Base2 p2:2097c28
Derived类分别继承了Base1和Base2,根据结果来看,均发生了多态。基类指针调用函数,调用的均是派生类的对象。
通过打印出了p1和p2的地址,发现他们相差了8个字节,就能明白了,在做类型转换的过程中,如果把地址传给第二个基类的指针的时候会自动把地址减去8,在64位系统下,刚好是一个指针的长度。因此p2指向的实际上是第二个虚函数指针的地址,这样,就能够实现多继承的多态了。
c++多继承多态的更多相关文章
- Winform打砖块游戏制作step by step第5节---重构代码,利用继承多态
一 引子 为了让更多的编程初学者,轻松愉快地掌握面向对象的思考方法,对象继承和多态的妙用,故推出此系列随笔,还望大家多多支持. 二 本节内容---重构代码,利用继承多态 1. 主界面截图如下: 2. ...
- java面向对象(封装-继承-多态)
框架图 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向对象的特点 ...
- 浅谈学习C++时用到的【封装继承多态】三个概念
封装继承多态这三个概念不是C++特有的,而是所有OOP具有的特性. 由于C++语言支持这三个特性,所以学习C++时不可避免的要理解这些概念. 而在大部分C++教材中这些概念是作为铺垫,接下来就花大部分 ...
- No2_4.接口继承多态_Java学习笔记_经典案例
import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import jav ...
- Java继承多态中的方法访问权限控制
java中的方法天生具有继承多态特性,这点与C++有很大不同(需要在父类方发上加virtual关键字),但用起来确实方便了许多. 最简单的继承多态 声明一个接口BaseIF,只包含一个方法声明 pub ...
- Java三大特性(封装,继承,多态)
Java中有三大特性,分别是封装继承多态,其理念十分抽象,并且是层层深入式的. 一.封装 概念:封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据 ...
- Java开发知识之Java的继承多态跟接口*
Java开发知识之Java的继承多态跟接口 一丶继承 1.继承的写法 在Java中继承的 关键字是 extends 代表一个类继承另一个类. 继承的含义以及作用: 继承就是基于某个父类的扩展.制定出来 ...
- -1-2 java 面向对象基本概念 封装继承多态 变量 this super static 静态变量 匿名对象 值传递 初始化过程 代码块 final关键字 抽象类 接口 区别 多态 包 访问权限 内部类 匿名内部类 == 与 equal
java是纯粹的面向对象的语言 也就是万事万物皆是对象 程序是对象的集合,他们通过发送消息来相互通信 每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象 每个对象都有它的类型 也就是 ...
- python面向对象之继承/多态/封装
老师说,按继承/多态/封装这个顺序来讲. 子类使用父类的方法: #!/usr/bin/env python # coding:utf-8 class Vehicle: def __init__(sel ...
- java继承多态和抽象类接口
一.继承 通过扩展一个已有的类,并继承该类的属性和行为,来创建一个新的类.已有的称为父类,新的类称为子类(父类派生子类,子类继承父类).(1)继承的优点: ①代码的可重用性: ②父类的属性 ...
随机推荐
- vue使用中遇到的,以及vue1.0到vue2.0新手踩的坑
最近再写一个vue的项目,视频中用的是vue1.0,但是现在vue已经2.0,所以踩了很多坑,先记录下来.理解有误再来修改. 路由问题 之前的路由是写在app.vue里边,而2.0的路由直接有个rou ...
- GitHub 使用说明
GitHub使用教程 附件是Github 使用说明: GitHub使用说明.pdf 目录 1 注册帐户... 2 2 登录帐户... 2 3 创建仓库... 2 4 ...
- Cordova配置与WebApp混合开发环境配置
好久都没来更新随笔了,这阵子比较忙,不过还是在不断的学习当中,今天给大家分享一下Cordova的配置与搭建WebApp混合开发环境的配置. 准备好了吗?让我们一步步来咯!!! 1.配置JDK环境 用的 ...
- Eclipse导入的User Libarary
在使用eclipse导入外部jar包时,经常使用Add User Libarary的方式,采用这种方式,外部的jar包没有直接添加到WEB-INF/libs下,那这些jar是在哪里引入的呢? 使用外部 ...
- springboot pom.xml记
本文包括: springboot 基本pom.xml配置 热部署 配置打包插件 maven pom.xml配置详解 1. springboot 基本pom.xml配置 <project xmln ...
- #2019-2020-4 《Java 程序设计》第九周总结
2019-2020-4 <Java 程序设计>第九周知识总结 第十一章:JDBC与MySQL数据库 11.1 MySQL数据库管理系统 下载安装: 11.2 启动MySQL数据库服务器 具 ...
- Python——教你画朵太阳花
用python中的turtle函数画个太阳花,有以下几个步骤 1.首先,我们在开始中找到Python语言的IDLE软件脚本 2.然后出现该软件界面,如图,点击上面的Eile 3.然后在 ...
- 有return的情况下try catch finally的执行顺序(转)
结论:1.不管有没有出现异常,finally块中代码都会执行:2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并没 ...
- Nginx服务器中配置非80端口的端口转发方法详解
这篇文章主要介绍了Nginx服务器中配置非80端口的端口转发方法详解,文中使用到了Nginx中的proxy_pass配置项,需要的朋友可以参考下 nginx可以很方便的配置成反向代理服务器: 1 2 ...
- Python的list循环遍历中,删除数据的正确方法
在遍历list,删除符合条件的数据时,总是报异常,代码如下: num_list = [1, 2, 3, 4, 5] print(num_list) for i in range(len(num_lis ...