class A{};
class B{
virtual void func0() {}
};
class C{
virtual void func1() {}
};
class D:public B, public C{
virtual void func2() {}
};
class E:public B, public C{
};
这里D和E大小一样,为啥,本身的虚基类表指针呢?发生了什么操作
#include <iostream>
using namespace std;
class A{};
class B
{
virtual void func0() {
cout << "B func0"<<endl;
}
};
class C
{
virtual void func1()
{
cout << "C func1"<<endl;
}
};
class D:public B , public C
{
virtual void func2()
{
cout << "D func2()" <<endl;
}
};
class E:public B, public C
{
};
int main()
{
D d;
long *p2Class = (long *)&d;
long *p2VTB = (long *) ( *p2Class );
//第一张虚函数表 begin
long *p2Fun = NULL;
p2Fun = (long *)(*(p2VTB));
((void (*) ())p2Fun)(); //cout-->B func0
p2Fun = (long *)(*(p2VTB + 1));
((void (*) ())p2Fun)(); //cout-->D func2
//第一张虚函数表 end
//第二张虚函数表 begin
long *p2VTC = (long *) ( *(p2Class + 1) );
p2Fun = (long *)(*(p2VTC));
((void (*) ())p2Fun)(); //cout-->C func1
/*
p2Fun = (long *)(*(p2VTC + 1));
((void (*) ())p2Fun)(); //报错
*/
//第二张虚函数表 end
return 0;
}
我是64位的, 验证得出, 本身的虚基类表指针被和B的虚函数指针放在同一张虚函数表里, C的虚函数表里没有.
一个类中,虚函数本身、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间的
http://blog.csdn.net/maxiaozhuang/article/details/39494725
一样大,因为存的不是虚函数指针,而是存的虚函数表的入口地址.
D 和 E 因为是多继承, 所以同时有来自B C的两张虚函数表.
你可以通过 (int *)&D 拿到虚函数表的入口地址, 也会是虚函数表里的第一个函数指针, 这个函数指针指向第一个被声明为虚函数的 函数的入口地址.
这个就是函数的入口地址 *(int *)&D , 你强转成 对应的函数指针类型 可以通过 ()方式调用去验证.
你理解有问题, 存的不是虚函数的指针, 而是虚函数表的入口地址. 不然你实例化多个对象, 每个对象都浪费那么多空间去存储所有的虚函数指针, 还不如建立一个虚函数表, 每个函数存几张虚函数表的入口地址 . 可以实现节耦合等等啊.