C++虚函数原理

类中的成员函数分为静态成员函数非静态成员函数,而非静态成员函数又分为普通函数虚函数

Q: 为什么使用虚函数

A: 使用虚函数,我们可以获得良好的可扩展性。在一个设计比较好的面向对象程序中,大多数函数都是与基类的接口进行通信。因为使用基类接口时,调用基类接口的程序不需要改变就可以适应新类。如果用户想添加新功能,他就可以从基类继承并添加相应的新功能。

Q: 简述C++虚函数作用及底层实现原理

A: 要点是要答出虚函数表虚函数表指针的作用。

C++中虚函数使用虚函数表和虚函数表指针实现,虚函数表是一个类的虚函数的地址表,用于索引类本身以及父类的虚函数的地址,假如子类重写了父类的虚函数,则对应在虚函数表中会把对应的虚函数替换为子类的函数的地址(子类中可以不是函数,但是必须同名);虚函数表指针存在于每个对象中(通常出于效率考虑,会放在对象的开始地址处),它指向对象所在类的虚函数表的地址;在多继承环境下,会存在多个虚函数表指针,分别指向对应不同基类的虚函数表。

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

虚函数表是每个有虚函数的对应一个。虚函数表指针是每个对象对应一个。

ref:

http://blog.csdn.net/haoel/article/details/1948051

http://songlee24.github.io/2014/09/02/cpp-virtual-table/

时间: 2024-12-27 22:43:43

C++虚函数原理的相关文章

虚函数原理解析

虚函数原理 虚函数的一般实现模型:每个类有一个虚函数表,内含该类中有作用的虚函数地址.每个 对象有一个vptr(虚函数表指针)指向虚函数表 如下Person类 class Person { public: virtual ~Person(); virtual string& getName(); virtual string& setName(); protected: string name_; }; 在Person的对象Jack中,有两个东西,一个是数据成员name_,一个是_Vptr

C++拾遗--虚函数原理

C++拾遗--虚函数原理 前言 C++的多态依赖虚函数来实现.若类存在虚函数,则每一个类的实例都维护了一个地址,这个地址指向虚函数表.虚函数表中存放的是类中所有虚函数的地址.下面我们找出虚函数表的地址,从而获得每个虚函数的地址,然后使用地址直接调用虚函数. 正文 1.空类的size #include <iostream> using namespace std; class MyClass { }; int main() { cout << "sizeof(MyClass

【C/C++学院】0823-静态联合编译与动态联合编译/父类指针子类指针释放/虚函数/纯虚函数概念以及虚析构函数/抽象类与纯虚函数以及应用/虚函数原理/虚函数分层以及异质链表/类模板的概念以及应用

静态联合编译与动态联合编译 #include <iostream> #include <stdlib.h> //散列 void go(int num) { } void go(char *str) { } //class //::在一个类中 class A { public: void go(int num) { } void go(char *str) { } }; void main() { ///auto p = go;编译的阶段,静态联编 void(*p1)(char *s

C++基础篇--虚函数原理

虚函数算是C++最关键和核心的内容之一,是组件的基础.下面先列出一些相关名词,再围绕它们举例说明虚函数的本质实现原理. 基础概念(英文部分来自C++编程思想) 1)绑定:Connectinga function call to a function body is called binding.(把函数调用和函数实现关联的过程) 2)早绑定:Whenbinding is performed before the program is run (by the compiler and linker

虚函数原理

虚函数表的数量与位置:编译器会为每个有虚函数的类创建一个虚函数表,该虚函数表将被该类的所有对象共享.编译器将虚函数表存放在了目标文件或者可执行文件的常量段,即代码区. 虚函数表指针(vptr)的数量与位置:如果1个类中存在一个虚函数,那么第一个地址永远都是指向虚函数列表的指针.子类没有vptr,子类的虚函数存放在第一个父类的虚函数表的最后,如果有覆盖,则覆盖掉相应父类的虚函数. lass Base { public: virtual void f() { cout << "Base:

c++ 深入理解虚函数

为什么使用虚函数?什么是虚函数?虚函数是为了解决什么问题? 面向对象的三大特征: 封装 多态 继承 普通虚函数 虚析构函数 纯虚函数 抽象类 接口类 隐藏 vs 覆盖 隐藏与覆盖之间的关系 早绑定和晚绑定 虚函数表 什么是多态? 相同对象收到不同消息或不同对象收到相同消息时产生的不同的动作. 静态多态 vs 动态多态 [-:>静态多态也叫做早绑定 class Rect //矩形类 { public: int calcArea(int width); int calcArea(int width,

类虚函数表原理实现分析(当我们将虚表地址[n]中的函数替换,那么虚函数的实现就由我们来控制了)

原理分析 当调用一个虚函数时, 编译器生成的代码会调用 虚表地址[0](param1, param2)这样的函数. 已经不是在调用函数名了. 当我们将虚表地址[n]中的函数实现改为另外的函数, 虚函数的实现就由我们来控制了. 实验 根据虚表原理, 实验一下修改自己程序的虚函数表项地址. 使编译器生成的代码执行一个虚函数A时, 执行的是我们自己定义的非虚函数B. 知识点 * 使用union赋值, 绕过编译器函数与变量强转赋值的限制 * 类成员函数指针的执行 * 修改和恢复自己的代码段属性 * 虚函

虚函数列表: 取出方法 // 虚函数工作原理和(虚)继承类的内存占用大小计算 32位机器上 sizeof(void *) // 4byte

#include <iostream> using namespace std; class A { public: A(){} virtual void geta(){ cout << "A:A" <<endl; } virtual void getb(){ cout << "A:B" <<endl; } }; class B :public A{ public: B(){} virtual void g

在类有成员变量的场景下, 按照虚表原理, 模拟虚函数实现

前言 当类没有成员变量的情况下,   类首地址有4个字节的空间, 这里可以放我们模拟出来的虚表入口地址. 当类有成员变量的情况下, 类首地址就是成员变量,  所以, 为了模拟虚表实现, 需要在成员变量前, 再定义一个int型变量, 用来存放模拟的虚表入口地址. 现在还得不到虚析构函数的地址, 暂时按照非虚析构函数进行模拟. 这个实验是在C++中模拟的. 模拟虚函数实现的用途 在非OOP语言(C语言)中, 模拟类的实现, 可以实现虚函数的效果. 效果 工程下载点 编译环境: vc6sp6 + wi