定义
虚函数(Virtual Function)
class Base {
public:
virtual void show() { cout << "Base show" << endl; }
};
复制代码
虚函数表(Virtual Function Table)
虚函数指针(Virtual Pointer)
定义:每个含有虚函数的类的对象(实例化出的)会持有一个指向相应虚表的指针,这个指针通常被称为虚指针(vptr)。vptr 是对象运行时的一部分,确保了当通过基类指针调用虚函数时,能够查找到正确的函数实现。
作用:在对象的生命周期开始时,构造函数会设置 vptr 以指向相应的虚函数表。如果有派生类对象,它的构造函数会更新 vptr,以指向派生类的虚函数表。这保证了通过基类的引用或指针调用虚函数也会执行最派生类的重写版本。
示例
#include <iostream>
using namespace std;
class Base {
public:
virtual void func1() { cout << "Base::func1" << endl; }
virtual void func2() { cout << "Base::func2" << endl; }
};
class Derived : public Base {
public:
void func1() override { cout << "Derived::func1" << endl; }
// func2() 继承自 Base
};
void printVTable(void* obj) {
cout << "vptr Address: " << obj << endl;
void** vTable = *(void***)obj;
cout << "VTable[0] (func1): " << vTable[0] << endl;
cout << "VTable[1] (func2): " << vTable[1] << endl;
}
int main() {
Base* base = new Base();
Derived* derived = new Derived();
cout << "Base object:" << endl;
printVTable(base);
cout << "\nDerived object:" << endl;
printVTable(derived);
delete base;
delete derived;
return 0;
}
复制代码
程序输出如下,可以看到没用重写的 func2 函数地址是一样的。
Base object:
vptr Address: 0x8c1510
VTable[0] (func1): 0x422270
VTable[1] (func2): 0x4222b0
Derived object:
vptr Address: 0x8c1530
VTable[0] (func1): 0x422330
VTable[1] (func2): 0x4222b0
复制代码
如下图所示:
面试题
(来自 2024 腾讯实习面试)场景题:一个类 A,里面有一个打印 helloworld 的虚函数,然后类 A 会在构造函数里调用这个虚函数,此时有个类 B,继承 A,重写了这个 helloworld 虚函数,问你在创建类 B 时,会打印 A 里的 helloworld 还是 B 里的。
代码如下:
class A {
public:
A() {
print();
}
virtual void print() {
cout << "A print" << endl;
}
};
class B : public A {
public:
void print() override {
cout << "B print" << endl;
}
};
int main() {
A* aTemp = new B();
delete aTemp;
}
复制代码
解答:基类构造函数执行的时候,派生类的部分尚未初始化,因此调用的虚函数不会下发到派生类中。
最终会打印 A print,而不是类 B 里重写的版本
文章转载自:江水为竭
原文链接:https://www.cnblogs.com/Az1r/p/18081756
体验地址:http://www.jnpfsoft.com/?from=001
评论