C++虚函数实现机制

C++中虚函数的实现机制主要是VTable和虚指针。详细如下:

class A {

public:

virtual void f1();

virtual void f2();

private:

int a;

}

class B {

public:

void f1();

private:

int b;

}

如上A,B两个类,编译器为A类准备了一个虚表VTableA如下:

A::f1的地址
A::f2的地址

编译器为B类准备的VTableB如下:

   B::f1的地址
   A::f2的地址

B类重写了f1,所以类B的VTable中记录的是B::f1()的入口地址,而f2是从A继承下来的,所以f2还是用A::f2的入口地址。

当定义B b = new B()时,编译器分配空间时,还会分配一个虚指针vptr指向B的VTable。

所以当使用如下语句:

A *pA = &b;  pA->f1();

编译器知道,f1是一个virtual成员函数,其入口地址放在表格的第一项,所以会转换为call*(pA->vptr)[0]。而这一项是放置B::f1的入口地址。

就实现了多态。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 20:46:37

C++虚函数实现机制的相关文章

C++虚函数运行机制

C++ 虚函数表解析 前言 C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有"多种形态",这是一种泛型技术.所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法.比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议. 关于虚函数的使用方法,我在这里不做过多的阐述.大家可以看看相关的C++的书籍.在这篇文章中,我只想从虚函

虚函数实现机制

说到虚函数的实现方法,我们就不得不说到动态联编(dynamic binding)和静态联编(static binding).静态联编意味着编译器能够直接将标识符和存储的物理地址联系在一起.每一个函数都有一个唯一的物理地址,当编译器遇到一个函数调用时,它将用一个机械语言说明来替代函数调用,用来告诉CPU跳至这个函数的地址,然后对此函数进行操作.这个过程是在编译过程中完成的(注:调用的函数在编译时必须能够确定),所以静态联编也叫前期联编(early binding).但是,如果使用哪个函数不能在编译

虚函数运行机制

class A { public: virtual void foo (void) { ... } virtual void bar (void) { ... } }; class B : public A { public: void foo (void) { ... } }; int main(){ A* pa = new A; pa->foo (); // A::foo pa->bar (); // A::bar --------------------- A* pa = new B;

匹夫细说C#:从园友留言到动手实现C#虚函数机制

前言 上一篇文章匹夫通过CIL代码简析了一下C#函数调用的话题.虽然点击进来的童鞋并不如匹夫预料的那么多,但也还是有一些挺有质量的来自园友的回复.这不,就有一个园友提出了这样一个代码,这段代码如果被编译成CIL代码的话,对虚函数的调用会使用call而非callvirt: override string ToString() { return Base.ToString(); } 至于为何是这样,匹夫在回复中也做了解释,因为上面那段代码其实相当于是这样的: override string ToSt

C++ 虚函数和虚继承浅析

本文针对C++里的虚函数,虚继承表现和原理进行一些简单分析,有希望对大家学习C++有所帮助.下面都是以VC2008编译器对这两种机制内部实现为例. 虚函数 以下是百度百科对于虚函数的解释: 定义:在某基类中声明为 virtual 并在一个或多个派生类中被重新定 义的成员函数[1] 语法:virtual 函数返回类型 函数名(参数表) { 函数体 } 用途:实现多态性,通过指向派生类的基类指针,访问派生类中同名覆盖成员函数 函数声明和定义和普通的类成员函数一样,只是在返回值之前加入了关键字"vir

C++ 虚函数 、纯虚函数、接口的实用方法和意义

也许之前我很少写代码,更很少写面向对象的代码,即使有写多半也很容易写回到面向过程的老路上去.在写面向过程的代码的时候,根本不管什么函数重载和覆盖,想到要什么功能就变得法子的换个函数名字,心里想想:反正函数重载本质也就是入栈了两个不同的函数. 回过头来讲,让我了解标题这三个概念的实际用处,还是在于我这第四次重写毕业论文的代码,将它改写成面向对象的时候,才理解的.在面向对象设计的过程中, 类是从抽象逐渐具体起来的,父类可以是非常非常抽象的东西,而最终实例化的子类就非常具体了.在这个继承的过程中,不断

虚函数和模板编程的一点共性和特征模板的一个例子

最近在看元编程中,对虚函数和模板编程有一点点感悟,写一篇博客简单总结一下. 虚函数和模板是C++里面很棒的特征,他们都提供了一种方法,让程序在编译中完成一些计算,去掉的这些计算在比较low的编程方式中,是需要在程序运行中执行的.在这里,我要强调的是:"在编译过程中完成一些计算". 我会举两个例子,一个是虚函数的,比较简单,另一个例子是关于特征模板的,在例子中,根据模板参数的类型自动选择模板的底层数据结构. 第一个例子是比较简单的虚函数的例子,有很多种水果的类型,我们有一个函数要展示他们

虚函数与虚继承小结

  虚函数的作用就是实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数:实现方法就是在函数返回值之前加上关键字"virtual":如下: #include <stdio.h> class A { public: void fn() { printf("fn in A\n"); } virtual void v_fn() { printf("virtual fn in A\n"); } }; class B : p

C++手稿:虚函数与多态

C++类继承带来了诸多好处:基类代码复用.通用的方法和属性.更好的可维护性, 然而最大的好处莫过于提供统一的接口.接口是一种对类型的抽象,它统一了一系列类的行为, 不同类的对象之间交互更加容易.Java.objective C等面向对象语言都提供了接口的概念, 在C++中,可以通过抽象类来实现一个接口. C++通过虚函数实现了多态:通过基类指针或引用调用虚函数时,会调用当前对象的实际类型中声明的函数. 为了这个特性,包含虚函数的C++对象中会存储一个虚函数表指针,来完成动态联编. 编译程序在编译