大家好,欢迎来到IT知识分享网。
Hi~!欢迎来到碧波空间,平时喜欢用博客记录学习的点滴,欢迎大家前来指正,欢迎欢迎~~
✨✨ 主页:碧波
📚 📚 专栏:C++ 系列文章
![]()
📚 虚表(Virtual Table)和虚表指针(vptr)是C++中实现多态性的重要机制。它们通过动态绑定(或运行时多态性)实现了在基类指针或引用下调用派生类的虚函数。
目录
虚函数(Virtual Function)
虚函数是在基类中声明为 virtual 的成员函数。在派生类中可以根据需要进行重写(override)。它允许在运行时动态地确定调用哪个版本的函数,这是实现多态性的一种关键机制。
虚函数表(Virtual Table,VTABLE)
虚表是每个包含虚函数的类的静态成员之一,它存储了类的虚函数的地址。每个类有一个对应的虚表,其中的每个条目是一个指向相应虚函数的指针。当类被定义时,编译器会在其虚表中生成对应的虚函数条目。
虚表指针(vptr)
虚表指针是一个隐藏的指针,存在于每个包含虚函数的类的对象中。它指向该类的虚函数表(虚表)。当调用一个虚函数时,实际上是通过对象的虚表指针找到对应的虚表,然后根据函数的偏移量来调用正确的函数。
虚表和虚表指针工作原理
🎯 通过示意图来更好地理解虚表和虚表指针的概念,有 Base 类和 Derived 类:
Base 类对象内存布局: +--------------+ | vptr (Base) | --> 指向 Base 类的虚表 +--------------+ | Base 类的数据 | +--------------+ Derived 类对象内存布局: +----------------+ | vptr (Derived) | --> 指向 Derived 类的虚表 +----------------+ | Derived 类的数据 | +----------------+
每个对象的开头都有一个虚表指针。这个指针指向其对应的类的虚表。例如,Base 类对象的虚表指针指向 Base 类的虚表,而 Derived 类对象的虚表指针则指向 Derived 类的虚表。
🎯 通过简单的示例代码,演示如何利用虚表和虚表指针实现动态多态性;
class Base { public: virtual void func1() { std::cout << "Base::func1()" << std::endl; } virtual void func2() { std::cout << "Base::func2()" << std::endl; } }; class Derived : public Base { public: void func1() override { std::cout << "Derived::func1()" << std::endl; } }; int main() { Base* basePtr; Derived derivedObj; basePtr = &derivedObj; // 虚函数的调用 basePtr->func1(); // 输出 "Derived::func1()" basePtr->func2(); // 输出 "Base::func2()" return 0; }
当编译器在编译的时候会分别为类Base和类Derived 创建属于各自类的虚函数表。并Derived 当创建父类指针指向对象的时候,会初始化vptr指针,指向该对象所属类的虚函数表。
通过指向子类对象的父类指针,调用成员函数时,会先判断是否为virtual 虚函数,如果是虚函数的话,会通过vptr访问对应的类虚函数表中所存放的成员函数指针。依次实现多态。
🎯 结合示例,总结工作过程。
虚函数声明与重写:
在基类中,如果一个函数被声明为虚函数(使用 virtual 关键字),它可以被派生类重写。
虚表的构建:
每个类的虚函数表在编译时构建。虚表中的每个条目存储了对应虚函数的地址,这些地址是相对于类的基址的偏移量。
虚表指针的初始化与使用:
当创建一个对象时,如果该对象所属的类有虚函数,编译器会在对象的内存布局中插入一个虚表指针。这个指针被初始化为指向该类的虚表的地址。
动态绑定:
当调用一个虚函数时,实际被调用的函数取决于对象的实际类型(而不是引用或指针的静态类型)。这是因为编译器会通过对象的虚表指针来查找对应的虚表,然后根据虚函数的偏移量来调用正确的函数实现。
🔥 虚表和虚表指针区别:
虚表属于类,虚表指针属于对象。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/110958.html
