1、创建子类对象时,会优先创建父类部分,再创建子类部分,也就是子类对象是包含了两部分内容,(父类部分+子类部分)(图1)
class TypeA { public: int a = 10; void v() {} }; class TypeB:public TypeA { public: int b = 20; void x() {} |
图1
图2
|
现在把obj_b地址赋值给TypeA类型的指针ptr_a,那么ptr_a认为其指向的就是TypeA对象,而且不会有任何问题,毕竟obj_b对象的前半部分就是来自TypeA类型(图2)
2、如果类型中含有虚函数,那么就会多出虚函数表(简称虚表)vftable,虚函数表中保存虚函数的指针,编译器生成一个虚表指针变量vfptr,指向该虚表(图3)
class TypeA { public: int a = 10; void virtual v() {} void virtual v2() {} }; class TypeB:public TypeA { public: int b = 20; void virtual x() {} void virtual v2() {} };
|
图3 |
有两张虚表,一张是TypeA类型的,一张是TypeB类型的。TypeA有两个虚函数,所以虚表中也有2个虚函数指针。TypeB的虚表中有3个虚函数,一个继承了TypeA的函数(TypeA::v),一个重新定义了TypeA的函数(TypeB::v2)
还一个是自己本身自带的函数(TypeB::v2)。
这里我们看到vfptr只有一个,这个是类型TypeA的,TypeB直接继承来用。vfptr是在构造函数中初始化的(这个是由编译器自动生成,程序员不知道),所以其实当我们创建b_obj对象时,会赋值两次。
第一次是在调用TypeA构造函数时赋值(赋值的是TypeA虚表),第二次是在TypeB构造函数中赋值(赋值的是TypeB虚表),第二次把第一次的覆盖了。
执行a_ptr->v() 从虚拟表冲找到TypeA::v执行,执行a_ptr->v2() 从虚拟表冲找到TypeB::v2执行。
标签:虚表,模型,漫谈,TypeA,C++,TypeB,public,v2,void From: https://www.cnblogs.com/fuyun2000/p/16782462.html