C++对象模型之数据成员模型(1)

第二章 数据成员模型

1.1.   继承与数据成员

考察下面的例子:

0001   class Concrete1
0002   {
0003   public :
0004     int val;
0005     char bit1;
0006   };
0007   class Concrete2 : public Concrete1
0008   {
0009   public :
0010     char bit2;
0011   };
0012   class Concrete3 : public Concrete2
0013   {
0014   public :
0015     char bit3;
0016   };

 

类继承关系如下:

 

Concrete1

 

 

Concrete2

 

 

Concrete3

 

正确的对象内存布局

 

Concrete1 Object             Concrete2 Object              Concrete3 Object

4

int val

1

char bit1

3

Padding 3 bytes

8

Concrete1

1

char bit2

3

Padding 3 bytes

12

Concrete2

1

char bit3

3

Padding 3 bytes

 

 

 

 

 

验证对象

0001   #include <iostream>
0002   //-------------------------------------------------------------------
0003   class Concrete1
0004   {
0005   public :
0006     int val;
0007     char bit1;
0008   };
0009   class Concrete2 : public Concrete1
0010   {
0011   public :
0012     char bit2;
0013   };
0014   class Concrete3 : public Concrete2
0015   {
0016   public :
0017     char bit3;
0018   };
0019   //-------------------------------------------------------------------
0020   int main()
0021   {
0022     cout << sizeof(Concrete1) << endl;
0023     cout << sizeof(Concrete2) << endl;
0024     cout << sizeof(Concrete3) << endl;
0025     int i;
0026     cin >> i;
0027   }

输出结果为:

8

12

16

从以上模型结构可以看出,子类继承了父类的数据,同时也继承了父类因补齐原则而引入的“多余的”字节。为什么在子类继承的同时不去除父类因补齐原则而引入的“多余的”字节呢?为什么不将模型转换成如下形式,以便更加节约内存,减少因类继承关系而造成的对象内存空间的浪费呢?

 

Concrete1 Object             Concrete2 Object              Concrete3 Object

4

int val

1

char bit1

3

Padding 3 bytes

4

int val

1

char bit1

1

char bit2

2

Padding 2 bytes

4

int val

1

char bit1

1

char bit2

1

char bit3

1

Padding 1 bytes

         


如此一来,三个对象的内存占用大小都变成8个字节,因而在创建多个派生类对象的时候,将更节约内存。

之所以不采用这样的模型,是因为该模型会在复制对象的时候产生不可预期的错误,例如:

0001   Concrete2 *pc2;
0002   Concrete1 *pc1;
0003   pc2 = new Concrete2;
0004   pc1 = new Concrete1;
0005   *pc2 = *pc1;

 

上述模型模型将在第五行产生不可预期的错误,这是因为复制Concrete1对象的时候会破坏Concrete2对象的数据成员。

 

bit2将被指定一个不确定的值,破环了原来的数据内容,这种行为不是所期望的。

Concrete1 Object                         Concrete2 Object

4

int val

1

char bit1

3

Padding 3 bytes

4

int val

1

char bit1

1

char bit2

2

Padding 2 bytes

Copy

 

 

 

 

 


同理,Concrete1 ---> Concrete2,Concrete2 -à Concrete3也都会破坏数据成员。

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

wxcwuxuchun

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值