浅谈动态多态实现原理

编程入门 行业动态 更新时间:2024-10-21 14:29:14

<a href=https://www.elefans.com/category/jswz/34/1769825.html style=浅谈动态多态实现原理"/>

浅谈动态多态实现原理

简介:  

        如果一个类中声明有虚函数,大多数编译器就会为这个类创建一个虚函数表(virtual function table)简称虚表(vtab)。
        虚表中存放了该类中所有虚函数的地址,虚表属于整个类,不属于某个具体的对象,该类所有对象共享虚表。

        当实例化该类对象时,会自动把该类虚表的首地址(简称为 虚指针 vptr)存在该对象中,当使用基类指针/基类引用 调用该虚函数时,大概的过程为:

基类指针/基类引用   -》具体对象 -》虚指针   -》 虚函数表   -》 具体虚函数地址   -》调用虚函数

大概图示如下:

 验证代码:

#include <iostream>using namespace std;class Parent {public:virtual void func1() {cout << "Parent::func1()" << endl;}virtual void func2() {cout << "Parent::func2()" << endl;}private:int a;virtual void func3() {cout << "Parent::func3()" << endl;}
};class Child : public Parent{public:/* 重写func2函数 */void func2() {cout << "Child::func2()" << endl;}private:int b;
};int main() {Child c;Parent *p;p = &c; /* 取基类对象的地址 */Child *pc = &c;/* 因为64位环境下指针大小为8,所以将其转换为long型的方便解引用 */long *pl = reinterpret_cast<long *>(pc);/* 将long型的地址转换为long*的指针 */long *vptr = reinterpret_cast<long *>(*pl);/* 定义一个函数指针PF */using PF = void (*)();/* 提取虚函数表中第一个元素 */PF pf1 = reinterpret_cast<PF>(vptr[0]);pf1();/* 提取虚函数表中第二个元素 */PF pf2 = reinterpret_cast<PF>(vptr[1]);pf2();/* 提取虚函数表中第三个元素 */PF pf3 = reinterpret_cast<PF>(vptr[2]);pf3();cout << "===================" << endl;/* 通过基类的指针调用 */p->func1();p->func2();return 0;
}

运行结果:

总结:

如果一个类中声明有虚函数,大多数编译器就会为这个类创建一个虚函数表,虚表中存放了该类中所有虚函数的地址,虚表属于整个类,不属于某个具体的对象,该类所有对象共享虚表。在子类中如果没有重写虚函数,会继承父类的虚函数,重写则会覆盖父类的虚函数。

彩蛋:

再验证过程中在父类中定义了一个私有的虚函数,但是在类外依旧能通过虚表地址调用它,从另一方面可以看出类的公有和私有权限只在编译阶段会判断。

更多推荐

浅谈动态多态实现原理

本文发布于:2024-02-26 22:09:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1704129.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:浅谈   原理   多态   动态

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!