我们可以看到每一个对象内都有一个指针指向vtable。
当一个基类声明一个虚函数后,在创建对象的时候会将该函数地址加入虚函数列表中,如果派生类重写了该函数,则会用新函数地址替换,如果其定义了新函数,则会将新函数的指针加入虚表中。
示例代码如下:
#include <stdio.h>
class base
{
public:
base(){};
virtual const char* feature(){return "test";};
virtual void name() {printf("basen");}
virtual ~base() { printf("~basen"); };
};
class plus : public base
{
public:
plus(/* args */){};
virtual void name() {printf("plusn");}
virtual void parant() {printf("basen");}
~plus() { printf("plusn"); };
};
int main()
{
base b;
printf("base: %ldn", size_t(&b));
plus p;
printf("plus: %ldn", size_t(&p));
}
仍然用 gdb 来验证,断点后通过 info vtbl 命令查看:
(gdb) info vtbl p vtable for 'plus' @ 0x555555755d08 (subobject @ 0x7fffffffe010): [0]: 0x555555554b4a <base::feature()> [1]: 0x555555554bf8 <plus::name()> [2]: 0x555555554c30 <plus::~plus()> [3]: 0x555555554c66 <plus::~plus()> [4]: 0x555555554c14 <plus::parant()> (gdb) info vtbl b vtable for 'base' @ 0x555555755d40 (subobject @ 0x7fffffffe008): [0]: 0x555555554b4a <base::feature()> [1]: 0x555555554b5c <base::name()>
当调用虚函数的时候,会在虚函数表中寻找对应的函数地址,因此它每一次调用动会多做一步匹配,相比静态联编的非虚函数要更加耗时。
需要注意的是构造函数不能声明为虚函数,而如果一个类作为除非不作为基类,否则建议声明一个虚析构函数。
总结
到此这篇关于C++ 基础教程之虚函数实例代码详解的文章就介绍到这了,更多相关c++ 虚函数内容请搜索易采站长站以前的文章或继续浏览下面的相关文章希望大家以后多多支持易采站长站!










