虚函数的实质是一个指针,指向虚函数表,这个表的位置我现在还不太清楚,不过这样做的好处是实现了动态确定一个函数
因为指针指向的位置可以变化,这样就可以实现override覆盖。子类覆盖父类方法的实质就是填写这个指针指向什么位置的过程
同样虚继承的实质也是一样,实际就是一个指针,就好像C++中声名一个对象,可以
A a;
也可以
A* a = new A();
第二种就是声明一个指针,指向一个堆中的对象。第一种就不是指针的形式
所以第二种形式就有动态性,是多态的基础
假设A的子类是ASon,使用语句
A* aa = new ASon();
就是把一个A类型的指针指向了ASon对象,调用的方法自然也就是ASon的了
经过以上分析就可以知道示例程序中A类中有一个int i占4字节,另外f()是一个指针,所以是4字节,所以sizeof(A)=8
这里需要引申一下的是多个虚函数只维护一个指向虚函数表的指针,也就是说如果A中还有这样几个函数
virtual void f1();
virtual void f2();
virtual void f3();
virtual void f4();
virtual void f5();
那么sizeof(A)还是8
类中所有的函数是不占空间的。如果在A中声明void F(); sizeof(A)没有变化
B是虚拟继承A所以比A多一个指针,也就是说sizeof(B)=12
C是一般的继承,与A大小一样,也是8