一个虚函数和虚继承的问题。

这个问题困惑好几天了。废话不多说,先上代码。

  1 #include <iostream> 
2 using namespace std;
3
4 class A
5 {
6 public:
7 virtual void aa()
8 {
9 }
10 private:
11 char k[3];
12 };
13
14 class B:public A
15 {
16 public:
17 virtual void bb()
18 {
19 }
20 private:
21 char j[3];
22 };
23
24 class C:public B
25 {
26 public:
27 virtual void cc()
28 {
29 }
30 private:
31 char i[3];
32 };
33
34 int main()
35 {
36 A a;
37 B b;
38 C c;
39 cout<<"sizeof(A):"<<sizeof(A)<<endl;
40 cout<<"sizeof(B):"<<sizeof(B)<<endl;
41 cout<<"sizeof(C):"<<sizeof(C)<<endl;
42 return 0;
43 }
44
45 打印结果:
46 sizeof(A):8//A有一个_vfptr的指向虚表的指针(4字节),加上char[3]补足是8字节。
47 sizeof(B):12//B继承A的全部(8字节),那加上char[3]补足一共是12字节,使用继承自A的_vfptr指向B的虚表
48 sizeof(C):16//同B的情况,都用A的虚函数表指针指向虚函数表。
49
50 但是如果 B、C虚继承自A
51 #include <iostream>
52 using namespace std;
53
54 class A
55 {
56 public:
57 virtual void aa()
58 {
59 }
60 private:
61 char k[3];
62 };
63
64 class B:virtual public A
65 {
66 public:
67 virtual void bb()
68 {
69 }
70 private:
71 char j[3];
72 };
73
74 class C:virtual public B
75 {
76 public:
77 virtual void cc()
78 {
79 }
80 private:
81 char i[3];
82 };
83
84 int main()
85 {
86 A a;
87 B b;
88 C c;
89 cout<<"sizeof(A):"<<sizeof(A)<<endl;
90 cout<<"sizeof(B):"<<sizeof(B)<<endl;
91 cout<<"sizeof(C):"<<sizeof(C)<<endl;
92 return 0;
93 }
94
95 在VS2008下打印结果为:
96 sizeof(A):8
97 sizeof(B):20
98 sizeof(C):32
99 而在GCC编译下,打印结果为:
100 sizeof(A):8
101 sizeof(B):16
102 sizeof(C):24
103
104 这是怎么得到的呢?
105

关于虚继承这个问题,以下有几种不同的回复,上截图:

另一种:

显然,MS的VS在这方面做了一些优化,跟其他编译器相比,在派生类中插入了一个偏移值表的指针,也就多了4个字节。

通过派生类来访问虚基类的上一个从偏移值表里的获得的偏移量。VS下的内存布局如下:


|C的虚函数表指针|C的偏移表指针|C的成员变量|A的虚表指针|A的成员变量|B的虚函数表指针|B的偏移表指针|B的成员变量 。 MS为什么通过偏移表来对虚基类的成员进行寻址,我还不晓得。

现在就把摘抄的写到这里。

=我弄明白,补上。

posted @ 2011-11-06 20:22  kanego  阅读(1536)  评论(0编辑  收藏  举报