虚继承,派生类重写基类虚函数,派生类大小的问题,具体看代码

#ifExample_1#defineUseVirtualBase1classA{public:A(){cout<<"createA!"<<endl;};virtual~... #if Example_1
#define UseVirtualBase 1
class A
{
public:
A()
{
cout << "create A!" << endl;
};
virtual ~A()
{
cout << "delete A!" << endl;
};
virtual void test()
{
cout << "test from A!" << endl;
}
public:
int a; // 4bytes
private:
char *p;// 内存对齐,补充为4bytes
/*
总共4+4+4=12bytes
*/
};
#if UseVirtualBase
class B : virtual public A
#else
class B : protected A
#endif
{
public:
B()
{
cout << "create B!" << endl;
};
~B()
{
cout << "delete B!" << endl;
};
/*
如果是虚继承,则此处表明子类有一个自己的虚函数表,
即要维护一个独立虚指针vfptr_B;
如果不是虚继承,则子类和父类共用一个虚函数表,共用一个虚指针
*/
virtual void test2()
{
}
virtual void test()
{
cout << "test from B!" << endl;
}
private:
static int st;
int d; // 4bytes
char *p; // 4bytes
char c; // 内存对齐,补充为4bytes
/*
(4+4+4)+12=24bytes
(4+4+4)+4+4+12=32bytes
*/
};
#endif

类A的大小是12,这没有问题
类B的大小输出是36,
我能理解的是:
1.类B自己的非静态成员变量,(4+4+4)
2.指向虚基类表的一个指针,4
3.指向自身虚函数表的一个指针,4
加起来是32,
试了一下,剩下的4Bytes,好像是因为重写了虚基类的虚函数,但是不明白其中的原因,跪求高手指点一下,谢谢了!!!
展开
 我来答
汤豆浅甜误新1v986
2012-08-02
知道答主
回答量:16
采纳率:0%
帮助的人:18万
展开全部
“如果是虚继承,则此处表明子类有一个自己的虚函数表”

我觉得你理解有点点错误,就算是虚继承,虚函数所在的表也只是同一份,不同的是,父类和子类都保存了一个指向该虚函数表的指针(而普通的继承只有一个指向虚函数表的指针)。

之所以会多于4Bytes 应该是B类中test2()这个虚函数父类中没有,又由于是虚继承的特殊性,所以在B类中test()和test2()不在同一个虚函数表中,B类另外用了一个指针保存test2()所在的虚函数表地址,所以这里B类才会有两个虚函数表,才会多出4Bytes,这4Bytes是另外一个虚函数表的地址,我是这么理解的!也实践证明过test2()并不在test()所在的虚表中,如有不同意见,或觉得有误,请提出,共同学习!
追问
额, 谢谢w3931242wwj的指教.
呵呵,理解这些,一直不知道怎么查看这些虚函数表,虚基类表,只能在网上东找西找!
能教教我你是咋做的吗??
追答
想获得虚函数表地址可以这样做,由于虚函数表的指针被隐藏了,不能直接得到,但是可以暴力强行获得,写一个没有任何数据的类,申明一个虚函数
class A
{
virtual void test(){}
}
这样,类A中只有一个4字节数据,就是V-Table(虚函数表)的指针
A a;
&a --->类a的地址
*(&a) ---->获得a中第一个数据,也就直接获得V-Tabe的指针
*(*(&a)) ---->获得虚函数表地址

比如,要证明该类所有实例都用的是同一张V-Table可以这样做:
创建两个实例
A a1;
A a2;

cout<<&(*(int*)(&a1))<<endl;
cout<<&(*(int*)(&a2))<<endl;
// 分别输出a1和a2 中 V-Talbe的指针的地址,两个指针肯定不同

cout<<&(*(int*)*(int*)(&a1))<<endl;
cout<<&(*(int*)*(int*)(&a2))<<endl;
//这里 输出V-Table地址,因为两个指针指向同一地址,肯定是一样的
看着有些晦涩.....
shania02
2012-08-03 · 超过10用户采纳过TA的回答
知道答主
回答量:43
采纳率:0%
帮助的人:23.2万
展开全部
推荐一本书给你《深度探索C++对象模型》
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式