所以我有这些课:
class Base {
public:
Base() {cout << "made a base" << endl;}
virtual void getType() const { cout << "Im a base" << endl;
virtual ~Base() {}
//other members...
}
class Derived: public Base {
public:
Derived() {cout << "made a derived" << endl;
virtual void getType() const { cout << "Im a derived" << endl; }
virtual ~Derived() {}
//other memebrs...
}
int main() {
Base* test = new Derived();
test->getType();
return 0;
}
输出:
made a base
made a derived
Im a derived
现在我知道输出是Im a derived
由于多态性造成的,但是我想知道它是如何在Vftables内部工作的,如何调用正确的函数,由于表的类型,vtable内部test
指向Base类getType()
函数,test
所以它如何知道是Derived::getType()
不是。Base::getType()
换句话说,我的程序在看到此声明时会在运行时做什么test->getType()
?
提前致谢。
当您这样做时Base* test = new Derived()
:
对象的V表指针test
设置为指向class的V表Derived
。
请注意,在通过创建对象时,new Derived()
您将显式调用classDerived
而不是class的函数(构造函数)Base
。
并且在调用此函数时,它将新对象的v-table指针设置为指向classDerived
而不是class的V-Table Base
。
AFAIK是(两个类的)实际V表,是由链接器在编译之前生成的。
补充说明:
程序不需要“知道”一个函数是virtual
。
在进行非虚拟函数调用的情况下,编译器将JUMP指令添加到恒定地址(即,非虚拟函数的地址,在编译过程中可以解析该地址)。
在调用虚拟函数的情况下,编译器将JUMP指令添加到存储在变量中(由其指向)的地址,该变量的值仅在运行时解析。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句