第二章 数据成员模型

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也都会破坏数据成员。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐