多态原理探究

理论知识:

  • 当类中声明虚函数时,编译器会在类中生成一个虚函数表
  • 虚函数表是一个存储类成员函数指针的数据结构
  • 虚函数表是由编译器自动生成与维护的
  • virtual成员函数会被编译器放入虚函数表中
  • 当存在虚函数时,每个对象中都有一个指向虚函数表的指针(C++编译器给父类对象、子类对象提前布局vptr指针;当进行howToPrint(Parent *base)函数是,C++编译器不需要区分子类对象或者父类对象,只需要再base指针中,找vptr指针即可。)
  • VPTR一般作为类对象的第一个成员

多态的实现原理

  当类中声明虚函数时,编译器会在类中生成一个虚函数表

  虚函数表是一个存储类成员函数指针的数据结构

  虚函数表是由编译器自动生成与维护的

  virtual成员函数会被编译器放入虚函数表中

  存在虚函数时,每个对象中都有一个指向虚函数表的指针(vptr指针)

换句话说:C++编译器为每一个含有虚函数子类和父类,提前部署一个vptr指针,然后通过vptr指针找到虚函数表,再通过虚函数表寻找后来人写的代码、再执行。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

说明1:

  通过虚函数表指针VPTR调用重写函数是在程序运行时进行的,因此需要通过寻址操作才能确定真正应该调用的函数。而普通成员函数是在编译时就确定了调用的函数。在效率上,虚函数的效率要低很多。

说明2:

  出于效率考虑,没有必要将所有成员函数都声明为虚函数

说明3 :

  C++编译器,执行HowToPrint函数,不需要区分是子类对象还是父类对象

如何证明vptr指针的存在?

#include <iostream>
using namespace std;

class A
{
public:
	void printf()
	{
		cout<<"aaa"<<endl;
	}
protected:
private:
	int a;
};

class B
{
public:
	virtual void printf()
	{
		cout<<"aaa"<<endl;
	}
protected:
private:
	int a;
};

void main()
{
	//加上virtual关键字 c++编译器会增加一个指向虚函数表的指针 。。。
	printf("sizeof(a):%d, sizeof(b):%d \n", sizeof(A), sizeof(B));
	cout<<"hello..."<<endl;
	system("pause");
	return ;
}

  

问题: 构造函数中能调用虚函数,实现多态吗?

解析:

1、对象中的VPTR指针什么时候被初始化?

  1)对象在创建的时,由编译器对VPTR指针进行初始化

  2)只有当对象的构造完全结束后VPTR的指向才最终确定

  3)父类对象的VPTR指向父类虚函数表

  4)子类对象的VPTR指向子类虚函数表

2、分析过程

原文地址:https://www.cnblogs.com/gd-luojialin/p/10358437.html

时间: 2024-11-25 18:30:10

多态原理探究的相关文章

多态原理探究-从C++编译器角度理解多态的实现原理

理论知识: 当类中声明虚函数时,编译器会在类中生成一个虚函数表. 虚函数表是一个存储类成员函数指针的数据结构. 虚函数表是由编译器自动生成与维护的. virtual成员函数会被编译器放入虚函数表中. 当存在虚函数时,每个对象中都有一个指向虚函数表的指针(C++编译器给父类对象.子类对象提前布局vptr指针:当进行howToPrint(Parent *base)函数是,C++编译器不需要区分子类对象或者父类对象,只需要再base指针中,找vptr指针即可.). VPTR一般作为类对象的第一个成员.

《coredump问题原理探究》Windows版 笔记

<coredump问题原理探究>Windows版 笔记 Debug 一.环境搭建 1.Win7捕获程序dump 2.Windbg符号表设置(Symbols Search Path) 二.WinDbg命令 三.函数栈帧 1.栈内存布局 2.栈溢出 3.栈的规律 4.定位栈溢出问题的经验方法 四.函数逆向 五.C内存布局 1.基本类型 2.数组类型 3.结构体 六.C++内存布局 1.类的内存布局 2.this指针 3.虚函数表及虚表指针 4.单继承 5.多继承(无公共基类) 七.STL容器内存布

Cocos2d-x 3.2:定时器的使用和原理探究(2)

Cocos2d-x 3.2:定时器的使用和原理探究(2) 本文转载至深入了解Cocos2d-x 3.x:定时器的使用和原理探究(2) 上一篇说到定时器的使用方法,这篇主要分析它的实现原理. 1.哈希链表 Cocos2d-x封装了一个结构体,叫做UT_hash_handle,只要在自定义的结构体中声明这个结构体变量,就实现了哈希链表,并且能使用一系列的哈希链表专用的宏.这个结构体的具体实现如下: 1 2 3 4 5 6 7 8 9 10 typedef struct UT_hash_handle 

Cocos2d-x 3.2:定时器的使用和原理探究(1)

Cocos2d-x 3.2:定时器的使用和原理探究(1) 本文转载至深入了解Cocos2d-x 3.x:定时器的使用和原理探究(1) 注:本文开始,引擎升级到Cocos2d-x 3.6 在游戏开发过程中,经常会遇到使用计时器的情况,例如:倒计时,定时炸弹等.scheduler是Cocos2d-x 2.x时代就已经存在的产物,主要用于各种延时函数以及各种每帧运行的函数.本文主要介绍scheduler的API函数以及使用方法. 首先,所有继承Node的类都可以使用scheduler,以下是Node类

zookeeper使用和原理探究(一)(转)

zookeeper介绍zookeeper是一个为分布式应用提供一致性服务的软件,它是开源的Hadoop项目中的一个子项目,并且根据google发表的<The Chubby lock service for loosely-coupled distributed systems>论文来实现的,接下来我们首先来安装使用下这个软件,然后再来探索下其中比较重要一致性算法. zookeeper安装和使用zookeeper的安装基本上可以按照 http://hadoop.apache.org/zookee

vmware nat模式原理探究,实现虚拟机跨网段管理

vmware nat模式原理探究: 理解nat模式,我们能更加了解主机与虚拟机之间如何通信,以及虚拟机如何实现上网. 以及便于我们分析虚拟机与主机无法通信和无法上外网的问题. 下面通过实战:虚拟网络拓扑,抓包分析. 为什么要探究nat模式? 从日常需求出发: 我们电脑上用到的虚拟机越来越多,需要固定IP,方便管理. 网络环境经常会变,我们可能在家办公和在公司办公网段不一样,每次要改为同一个网段再连接使用,比较麻烦. 首先理解vmware的三种模式: bridge模式:相当于一台hub,真实主机与

Cocos2d-x 3.2:定时器的使用和原理探究(3)

Cocos2d-x 3.2:定时器的使用和原理探究(3) 本文转载至[深入了解cocos2d-x 3.x]定时器(scheduler)的使用和原理探究(3) 上篇文章分析到了定时器的定义,这篇的重点就是定时器是如何运行起来的. 1.从main中寻找定时器的回调 讲定时器的运行,就不得不触及到cocos2dx的main函数了,因为定时器是主线程上运行的,并不是单独线程的,所以它的调用必然会在main函数中,每帧调用. 以下代码就是win32平台下的main函数 [cpp] view plainco

DNN原理探究系列之目录与序章篇

序言: 神经网络结构,作为最成功的机器学习模型之一,其工作原理一直被埋藏得比较深,其解释性以至于被称为黑盒. 自己对于DNN的理解也只能算刚踏入了门槛,对于人脑的原理与DNN原理之间的互通性,一直是非常深信的,所以想一窥DNN成功背后的数学原理. 通过DNN原理探究系列博文,希望能总结归纳已经理解的知识点,梳理清楚知识点之间的关系结构,同时探讨各种流派对于DNN原理的解读. 目录会随着自己掌握的知识量逐渐扩展新的分支,以此记录自己的学习历程. 当前知识结构树(2017-11-11) DNN结构与

go---&gt;共享内存和通信两种并发模式原理探究

共享内存和通信两种并发模式原理探究 并发理解 人类发明计算机编程的本质目的是为了什么呢?毫无疑问是为了解决人类社会中的各种负责业务场景问题.ok,有了这个出发点,那么想象一下,比如你既可以一心一意只做一件事,你也可以同时做多件事,比如,你计划今天上午计划就是看足球比赛,ok,你今天的工作就是串行的,单进程的,你只需要完成一件事.但是不巧呢,你妈妈说让你帮她切肉,你妈妈上午要出门有点事,同时不巧呢,你老婆说她上午也要出门,让你帮着打扫家里卫生,这时你今天就要同时做三件事,看比赛,切肉,打扫卫生.这