虚指针存在证明及虚函数表

简介:
C++多态的实现原理是依赖虚指针来辨别详细使用家族类中的哪一个函数。

下面就来证明虚指针的存在。 我们知道,指针的大小在普通情况下是4个字节,所以我们建立一个虚函数,再来计算该类的大小,便能够验证虚函数的存在。

代码例如以下:

#include <iostream>
using namespace std;

class A
{
public:
                 void print ()
                {

                }
private:
                 int a ;
};

class B
{
public:
                 virtual void print()
                {

                }
private:
                 int a ;
};


void main ()
{
                 cout << "sizeof(A)" << sizeof( A) << endl ;
                 cout << "sizeof(B)" << sizeof( B) << endl ;
                 system("pause" );
}

执行结果: 
这里写图片描写叙述 
A类与B类的,唯一区别就是在B类中 print()变成了一个虚函数,实验结果看到B类却比A类多出了4个字节。那说明在B类中。编译器隐藏的加入了一个虚指针的成员变量。

接下来在验证。一个类中。有多个虚函数。会不会分配多个虚指针:

#include <iostream>
using namespace std;

class B
{
public:
                 virtual void print()
                {

                }
                 virtual void print2()
                {

                }
private:
                 int a ;
};

void main ()
{
                 cout << "sizeof(B)" << sizeof( B) << endl ;
                 system("pause" );
}

执行结果: 
这里写图片描写叙述 
这就说明了,一个类中无论有几个虚函数,都仅仅会生成一个虚指针变量。 
这个虚指针变量实质上是指向一个虚函数表。我们先来看下什么是虚函数表。

虚函数表定义: 
类的虚函数表是一块连续的内存,每一个内存单元中记录一个JMP指令的地址。

注意的是,编译器会为每一个有虚函数的类创建一个虚函数表。该虚函数表将被该类的全部对象共享。

类的每一个虚成员占领虚函数表中的一行。假设类中有N个虚函数。那么其虚函数表将有N*4字节的大小。也就是说虚函数表是一块连续的内存。每一个虚成员。都会占领一块内存空间。

在平时设计代码是假设明白不须要使用虚函数,那就不要随便使用: 
1 主要原因是,虚指针调用虚函数是在程序执行时进行的,所以须要通过寻址操作才干找到真正应该调用的函数,而普通成员函数是在编译时就确定了调用的函数。不须要寻址操作。因此在效率上。虚函数的效率要低非常多。 
2 其次。由于他会在虚函数表中多占领一块内存空间,浪费空间。





本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5312823.html,如需转载请自行联系原作者

相关文章
|
4天前
|
Java 编译器 程序员
Java多态背后的秘密:动态绑定如何工作?
本文介绍了Java中多态的实现原理,通过动态绑定和虚拟方法表,使得父类引用可以调用子类的方法,增强了代码的灵活性和可维护性。文中通过具体示例详细解析了多态的工作机制。
18 4
|
2月前
|
存储 安全 编译器
指针的深入理解与陷阱
指针的深入理解与陷阱
48 0
|
4月前
|
存储 程序员 C++
程序员必知:【C++】虚函数表vtable理解
程序员必知:【C++】虚函数表vtable理解
27 0
|
5月前
|
C++
第十二章:C++中的this指针详解
第十二章:C++中的this指针详解
44 0
|
11月前
|
编译器 C语言 C++
一分钟搞懂什么是this指针(未涉及静态成员和函数)
一分钟搞懂什么是this指针(未涉及静态成员和函数)
|
11月前
|
存储 Cloud Native 编译器
C++ 虚函数表和虚函数表指针的创建时机
C++ 虚函数表和虚函数表指针的创建时机
函数指针、函数指针数组、计算器+转移表等归纳总结
函数指针、函数指针数组、计算器+转移表等归纳总结
|
存储 编译器 C++
【C++要笑着学】虚函数表(VBTL) | 观察虚表指针 | 运行时决议与编译时决议 | 动态绑定与静态绑定 | 静态多态与动态多态 | 单继承与多继承关系的虚表(二)
虚表是编译器的实现,而非C++的语言标准。上一章我们学习了多态的概念,本章我们深入探讨一下多态的原理。文章开头先说虚表指针,观察编译器的查表行为。首次观察我们先从监视窗口观察美化后的虚表 _vfptr,再透过内存窗口观察真实的 _vfptr。我们还会探讨为什么对象也能切片却不能实现多态的问题。对于虚表到底存在哪?我们会带着大家通过一些打印虚表的方式进行比对!铺垫完虚表的知识后,会讲解运行时决议与编译时决议,穿插动静态的知识点。文章的最后我们会探讨单继承与多继承的虚表,多继承中的虚表神奇的切片指针偏移问题,这块难度较大,后续我们会考虑专门讲解一下,顺带着把钻石虚拟继承给讲了
366 1
【C++要笑着学】虚函数表(VBTL) | 观察虚表指针 | 运行时决议与编译时决议 | 动态绑定与静态绑定 | 静态多态与动态多态 | 单继承与多继承关系的虚表(二)
|
存储 编译器 C++
【C++要笑着学】虚函数表(VBTL) | 观察虚表指针 | 运行时决议与编译时决议 | 动态绑定与静态绑定 | 静态多态与动态多态 | 单继承与多继承关系的虚表(一)
虚表是编译器的实现,而非C++的语言标准。上一章我们学习了多态的概念,本章我们深入探讨一下多态的原理。文章开头先说虚表指针,观察编译器的查表行为。首次观察我们先从监视窗口观察美化后的虚表 _vfptr,再透过内存窗口观察真实的 _vfptr。我们还会探讨为什么对象也能切片却不能实现多态的问题。对于虚表到底存在哪?我们会带着大家通过一些打印虚表的方式进行比对!铺垫完虚表的知识后,会讲解运行时决议与编译时决议,穿插动静态的知识点。文章的最后我们会探讨单继承与多继承的虚表,多继承中的虚表神奇的切片指针偏移问题,这块难度较大,后续我们会考虑专门讲解一下,顺带着把钻石虚拟继承给讲了
600 0
【C++要笑着学】虚函数表(VBTL) | 观察虚表指针 | 运行时决议与编译时决议 | 动态绑定与静态绑定 | 静态多态与动态多态 | 单继承与多继承关系的虚表(一)
|
编译器 Linux C语言
c++筑器 一把不同于C的武器 缺省参数,函数重载超底层讲解
缺省参数是声明或定义函数时为函数的参数指定一个默认值,这个就是缺省值。在调用该函数时,如果没有指定实参则采用该缺省值,否则使用指定的实参
121 0
c++筑器 一把不同于C的武器 缺省参数,函数重载超底层讲解