转载:多态性与虚函数表——内存分布
http://blog.sina.com.cn/s/blog_7c983ca60100yn1r.html
http://blog.sina.com.cn/s/blog_60e96a410100lirk.html 虚表这里,自己搞懂了,过一段时间就又忘了,尤其是有虚函数的时候整个内存的分布情况。转载一篇日志,对其进行整理,方便自己以后查阅。 构成对象本身的只有数据,非静态成员函数与对象的关系就是绑定,绑定的中介是this指针。成员函数为该类所有对象共享。 上述类图的解释:B的V2覆盖了A的V2,C的V1覆盖了A的V1,C的V3覆盖了B的V3。( 区分:覆盖、重载、隐藏、重写)
D的V3覆盖了B3的V3,另外D有一个新的虚函数VD。 Class D的内存模型
C++中的成员和函数,有静态和非静态。
1、非静态数据成员:放在每一个对象体内,作为对象专有的数据成员。
2、静态数据成员:被提取出来放在程序的静态数据区内,为该类所有对象共享,因此只存在一份。( 引申下,一个类模板中的静态数据成员实例化成模板类之后有几份?思考下。)
3、静态和非静态成员函数:最终都被提取出来放在程序的代码中并为该类所有对象共享。因每一个成员函数也只能存在一份代码尸体。 在C++中的类的成员函数都是保存在静态存储区中,那静态函数也是保存在静态存储区中,他们都是在类中保存同一个备份。
4、单继承的对象的内存布局:第一个为虚函数表指针vtbl,其后为成员且 先基类后子类。虚函数表里包含了所有虚函数的地址,以NULL结束。 虚函数如果子类有重写,就由子类的重新的代替。
单继承的对象的布局,第一个为虚函数表指针Vtbl,其后为成员且先基类后子类,虚函数表里包含了所有的虚函数的地址,以NULL结束。虚函数如果子类有重写,就由子类的重新的代替。( 注意,虚函数表是类所有,而虚函数表指针才是每个对象所有的,所以有虚函数的对象的地址会增加4,是指针的长度)
5、多重继承:所有的虚函数也都包含在虚函数表中,但不同的是多重继承有多个虚函数表, (1)当子类对父类的虚函数有重写时,子类的函数替换父类的函数在对应的虚函数位置,(2)当子类有新的虚函数时,这些虚函数被加在第一个虚函数表的后面。