关于

  • 本文演示环境:VS2017+32位程序。
  • 纯虚函数是一种特殊的虚函数。可以预测到:虚函数的结论同样适用纯虚函数,但是纯虚函数是一种特殊的存在,还是看看实际结果。
  • 代码写的不够规范: 因为任何带虚函数的类的析构函数都应该是虚析构函数。但是我这里没有写出来,目的是缩短文章篇幅。

结论

1.虚函数表指针 和 虚函数表

  • 1.1 影响虚函数表指针个数的因素只和派生类的父类个数有关。多一个父类,派生类就多一个虚函数表指针,同时,派生类的虚函数表就额外增加一个
  • 1.2 派生类和父类同时含有虚函数,派生类的虚函数按照父类声明的顺序(从左往右),存放在继承的第一个父类中虚函数表后面,而不是单独再额外建立一张虚函数表
  • 1.3 按照先声明、先存储、先父类、再子类的顺序存放类的成员变量
  • 1.4 无论是派生类还是父类,当出现了虚函数(普通虚函数、虚析构函数、纯虚函数),排在内存布局最前面的一定是虚函数表指针

2.覆盖继承

其实,覆盖继承不够准确。

2.1 成员变量覆盖

  • 派生类和父类出现了同名的成员变量时,派生类仅仅将父类的同名成员隐藏了,而非覆盖替换
  • 派生类调用成员变量时,按照就近原则,调用自身的同名变量,解决了当调用同名变量时出现的二义性的现象

2.2 成员函数覆盖

需要考虑是否有虚函数的情况

存在虚函数的覆盖继承

父类和派生类出现了同名虚函数函数((普通虚函数、纯虚函数),派生类的虚函数表中将子类的同名虚函数的地址替换为自身的同名虚函数的地址-------多态出现

不存在虚函数的覆盖继承

父类和派生类同时出现同名成员函数,这与成员变量覆盖继承的情况是一样的,派生类屏蔽父类的同名函数

1.单一继承

1.1 基类仅含有一个纯虚函数

1.1.1 代码

class baseD
{
public:
virtual void jumping() = 0;
int _mz = 100;
}; // 派生类
class deriveA : public baseD
{
public:
int _me = 3;
int _mf = 4;
};

1.1.2 内存分布

1>class deriveA	size(16):
1> +---
1> 0 | +--- (base class baseD)
1> 0 | | {vfptr}
1> 4 | | _mz
1> | +---
1> 8 | _me
1>12 | _mf
1> +---
1>
1>deriveA::$vftable@:
1> | &deriveA_meta
1> | 0
1> 0 | &baseD::jumping
  • 果然,与单一继承中基类只有一个虚函数的情况是完全一致的。

1.2 基类增加到2个纯虚函数

1.2.1 代码

class baseD
{
public:
virtual void jumping() = 0;
virtual void turning() = 0;
int _mz = 100;
}; // 派生类
class deriveA : public baseD
{
public:
int _me = 3;
int _mf = 4;
};

1.2.2 内存分布

1>class deriveA	size(16):
1> +---
1> 0 | +--- (base class baseD)
1> 0 | | {vfptr}
1> 4 | | _mz
1> | +---
1> 8 | _me
1>12 | _mf
1> +---
1>
1>deriveA::$vftable@:
1> | &deriveA_meta
1> | 0
1> 0 | &baseD::jumping
1> 1 | &baseD::turning
  • 分布情况与上面1.1中内存分布一致。

c++内存分布之纯虚函数的更多相关文章

  1. c++ 虚函数和纯虚函数

    在你设计一个基类的时候,如果发现一个函数需要在派生类里有不同的表现,那么它就应该是虚的.从设计的角度讲,出现在基类中的虚函数是接口,出现在派生类中的虚函数是接口的具体实现.通过这样的方法,就可以将对象 ...

  2. C++ - 虚基类、虚函数与纯虚函数

    虚基类       在说明其作用前先看一段代码 class A{public:    int iValue;}; class B:public A{public:    void bPrintf(){ ...

  3. c++虚函数,纯虚函数,抽象类,覆盖,重载,隐藏

    C++虚函数表解析(转) ——写的真不错,忍不住转了  http://blog.csdn.net/hairetz/article/details/4137000 浅谈C++多态性  http://bl ...

  4. C++纯虚函数

    本文较为深入的分析了C++中虚函数与纯虚函数的用法,对于学习和掌握面向对象程序设计来说是至关重要的.具体内容如下: 首先,面向对象程序设计(object-oriented programming)的核 ...

  5. C++学习25 纯虚函数和抽象类

    在C++中,可以将成员函数声明为纯虚函数,语法格式为: ; 纯虚函数没有函数体,只有函数声明,在虚函数声明结尾加上=0,表明此函数为纯虚函数. 最后的=0并不表示函数返回值为0,它只起形式上的作用,告 ...

  6. 从零开始学C++之虚函数与多态(二):纯虚函数、抽象类、虚析构函数

    一.纯虚函数 虚函数是实现多态性的前提 需要在基类中定义共同的接口 接口要定义为虚函数 如果基类的接口没办法实现怎么办? 如形状类Shape 解决方法 将这些接口定义为纯虚函数 在基类中不能给出有意义 ...

  7. C++ Primer--虚函数与纯虚函数的区别

    首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数. 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数. 定义一个函数为纯虚函数,才代表函数没有被实现. 定义纯虚函数是为了实 ...

  8. c++,纯虚函数与抽象类

    1.纯虚函数的定义: (1)虚函数被“初始化”为0的函数.声明纯虚函数的一般形式是virtual 函数类型 函数名(参数表列) =0;(2)纯虚函数没有函数体:(3)最后面的“=0”并不表示函数返回值 ...

  9. c++中虚函数和纯虚函数定义

    只有用virtual声明类的成员函数,使之成为虚函数,不能将类外的普通函数声明为虚函数.因为虚函数的作用是允许在派生类中对基类的虚函数重新定义.所以虚函数只能用于类的继承层次结构中. 一个成员函数被声 ...

随机推荐

  1. (转载)Java生成和操作Excel文件

    JAVA EXCEL API:是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该API非Windows操作系统也可以通过 ...

  2. python基础实战

    字符串的互相转换 字典的排序 字典的排序可以直接把,key值或者,values拿出来排序 也可以用dict.items拿出所有的key,value的值再加key=lambda x:x[1] 来排序. ...

  3. C语言中的各种字符串输入方法

    C语言从stdin读取一行字符串的几种方法 gets gets函数的头文件是<stdio.h>,原型如下: char *gets(char *s); gets从stdin中读入一行内容到s ...

  4. cvc-complex-type.2.3: Element 'servlet' cannot have character [children], because the type's content

    错误原因:粘贴代码 <servlet> <servlet-name>barServlet</servlet-name> <servlet-class>S ...

  5. 技术管理进阶——Leader的模型、手段及思维

    这里可以添加关注交流一下嘛-- 本文更多的是个人认知,有不足请批评. ​Case 在之前一次年底考评的时候,有一位leader将一个案例同时用到了自己和下属身上,老板发出了责问: 这个项目到底你是负责 ...

  6. ache

    ache和pain可能没啥差别,头疼和头好痛都对.从词典来看,有backache, bellyache, earache, headache, heartache, moustache/mustach ...

  7. day07 Linux配置修改

    day07 Linux配置修改 昨日回顾 1.系统目录 /etc :系统配置目录 /bin-> /usr/bin :保存常用命令的目录 /root :超级管理员目录 /home :普通管理员目录 ...

  8. 商业爬虫学习笔记day4

    一.获取登录后页面信息的两种方法 1.第一种方法: 人为把有效cookies加到请求头中,代码如下 import urllib.request # 确定url url = "https:// ...

  9. Excel 数据验证:分类选择及输入限制

    几个简单设置让你的数据不再出错 如何快速选择某一大类中的细分小类 多级菜单 注意:引用可以创建二级目录,但是引用前应先用公式定义名称,然后引用,引用只能在本sheet操作.

  10. Linux系统分区及挂载点

    一.关于Linux的分区情况 虽然硬盘分区表中最多能存储四个分区,但我们实际使用时一般只分为两个分区,一个是主分区(Primary Partion)一个是扩展分区(extended partition ...