1、题目如下
2、解析
1)编制头文件如下
#ifndef FRUITW4_H_
#define FRUITW4_H_
class Fruit
{
public:
Fruit(int n, double w, char c) :no(n), weight(w), key(c){ }
void print() { }
virtual void process() { }
private:
int no;
double weight;
char key;
};
class Apple:public Fruit
{
public:
Apple(const Fruit& f, int s, char t) :Fruit(f), size(s), type(t){ }
void save(){ }
virtual void process() { }
private:
int size;
char type;
};
#endif
2) 主程序测试
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
Fruit f = Fruit(10, 2.5, 'a');
Apple a = Apple(f, 10, 'a');
cout << sizeof(Fruit) << endl;
cout << sizeof(Apple) << endl;
return 0;
}
/*输出结果:
32
40
*/
3)代码解析
a、本程序由VS2013中完成,由测试结果可知,基类Fruit类的大小为32字节,派生类Apple类为40字节。测试结果比预想的要大,按照初次设想,Fruit类中包含int,double,char =>对应内存4+8+1 = 13字节;Apple类包含父类数据加本身(int,char)数据即13 + 4 + 1 = 18字节,存在什么问题呢?
b、查找相关资料后可知,一方面在基类和派生类中都存在虚函数(vptr),指向对应的虚表(vtbl),那么内存就会包括其指针;另一方面,内存的体系结构是对齐的,有一定的对齐规则。(网上参考资料内存对齐规则)
- 数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。
- 结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
- 收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.
c、根据对齐规则绘制对象模型图如下: