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

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

复制代码
  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 @   kanego  阅读(1541)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示