前言

虚函数执行速度要稍慢一些。为了实现多态性,每一个派生类中均要保存相应虚函数的入口地址表,函数的调用机制也是间接实现。所以多态性总是要付出一定代价,但通用性是一个更高的目标。

实验环境

Windows10 企业版

Visual Studio2017 15.8.1

引入虚函数后内存大小变

没有虚函数时类占用内存大小

#include<iostream>
using namespace std; class Base
{
public:
Base()
{
cout << "Create Base" << endl;
}
~Base()
{
cout << "Free Base" << endl;
}
public:
void Show()
{
cout << "This is Base Show()" << endl;
}
private:
int x;
}; void main()
{
cout << sizeof(Base) << endl;
Base b;
}

占用内存为4字节。在x86 模式下,整形变量大小为4字节

有虚函数时类占用内存大小

#include<iostream>
using namespace std; class Base
{
public:
Base()
{
cout << "Create Base" << endl;
}
~Base()
{
cout << "Free Base" << endl;
}
public:
virtual void Show()
{
cout << "This is Base Show()" << endl;
}
private:
int x;
}; void main()
{
cout << sizeof(Base) << endl;
Base b;
}

占用内存为8字节。在x86 模式下,整形变量大小为4字节。剩下4字节是虚函数表指针,指针变量在x86下占内存大小4字节。

代码中只定义了一个虚函数,定义多个虚函数,类的大小还是8。虚函数表的指针指向的是虚函数表的入口地址

虚函数表

 #include<iostream>
using namespace std; class Base
{
public:
Base()
{
cout << "Create Base" << endl;
}
~Base()
{
cout << "Free Base" << endl;
}
public:
virtual void Show()
{
cout << "This is Base Show()" << endl;
}
virtual void Print()
{
cout << "This is Base Print()" << endl;
}
void Fun()
{
cout << "This is Base Fun()" << endl;
}
private:
int x;
}; class D :public Base
{
public:
D()
{}
~D()
{}
public:
void Show()
{
cout << "This is D Show()" << endl;
}
void Fun()
{
cout << "This is D Fun()" << endl;
}
virtual void List()
{
cout << "This is D List()" << endl;
}
private:
int y;
}; void main()
{
D d;
}

虚函数表前后变化

虚函数表在构造父类的时候会记录所有父类的虚函数

这里面少显示了子类的List虚方法,少显示是编译器的问题。但是你不能通过父类指针访问子类List()方法,因为List超出了父类范围。

子类构造完成后,子类重写了父类的虚函数,虚函数表中的虚函。数就变成了子类的。狸猫混太子,偷梁换柱的意思

C++——多态实现原理分析的更多相关文章

  1. c/c++ 多态的实现原理分析

    多态的实现原理分析 当类里有一个函数被声明成虚函数后,创建这个类的对象的时候,就会自动加入一个__vfptr的指针, __vfptr维护虚函数列表.如果有三个虚函数,则__vfptr指向的是第一个虚函 ...

  2. 【C#多态】as 类型检测(原理分析) ---用于多态检

    as(OpCodes.Castclass)功能:测试对象引用(O 类型)是否为特定类的实例.相当于:expression is type ? (type)expression : (type)null ...

  3. AIDL原理分析

    季春初始,天气返暖,新冠渐去,正值学习好时机.在Android系统中,AIDL一直在Framework和应用层上扮演着很重要的角色,今日且将其原理简单分析.(文2020.03.30) 一.开篇介绍 1 ...

  4. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  5. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

  6. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  7. Android中Input型输入设备驱动原理分析(一)

    转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...

  8. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  9. Camel运行原理分析

    Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...

随机推荐

  1. Swift 4.0 Xib实现Button调整

    1.Xib画的界面按钮,代码中进行调整按钮图片在上,文字在下: 代码中修改按钮的位置比较好: payButton.titleEdgeInsets = UIEdgeInsetsMake((payButt ...

  2. Redis概述与基本操作

    redis教程 概述 redis是一种nosql数据库,他的数据是保存在内存中,同时redis可以定时把内存数据同步到磁盘,即可以将数据持久化,并且他比memcached支持更多的数据结构(strin ...

  3. C# 文档注释规范

    C# 提供一种机制,使程序员可以使用含有 XML 文本的特殊注释语法为他们的代码编写文档.在源代码文件中,具有某种格式的注释可用于指导某个工具根据这些注释和它们后面的源代码元素生成 XML.使用这类语 ...

  4. 基于python的App UI自动化环境搭建

    Android端Ui 自动化环境搭建 一,安装JDK.SDK 二,添加环境变量 Widows:1.系统变量→新建 JAVA_HOME 变量E:\Java\jdk1.7.0 jdk安装目录 2.系统变量 ...

  5. mysql navcat备份使用详解

    mysql navcat备份使用详解 点击备份 然后新建备份 然后选择要备份的表 就可以了 以后这个表删除了 内容变更了 都可以点击 还原备份就可以了

  6. 好消息!iconfont+开始支持彩色图标

    想必关注iconfont的同学都知道,iconfont最近做出了一次重大升级,升级成为iconfont+了,而这次更新,iconfont+居然开始支持彩色图标,这意味着我们能够使用更具有特色更形象的全 ...

  7. win10 linux Ubuntu 18.04更换国内源

    安装了win10的linux bash 版本为ubuntu 18.04 首先查询自己的linux版本信息 cat /etc/issue   然后对系统的镜像源文件进行备份,再修改镜像源文件/etc/a ...

  8. QT qml---- loader使用方法

    "简洁是智慧的灵魂,冗长是肤浅的藻饰"------------------<哈姆莱特>莎士比亚 Import Statement: import QtQuick 2.5 ...

  9. twemproxy配置

    redis多主从,多节点,读写分离架构. nutcracker.yml的twemproxy配置 #redis_main是twemproxy所控制redis主从集群逻辑名称 redis_main: #t ...

  10. nginx tar包安装 包含openssl,rewrite,stream,sticky 等模块

    最近需要使用nginx 但是发现有时缺少一些模块. 所以 在学习如何增加上相应的模块. 主要学习的网站: 沧海书生 Ansible爱好者 https://www.cnblogs.com/tssc/p/ ...