1. 运行结果
先上结论,测试代码见文末。
在Visual Studio 2015 Community中运行得到的结果如下:
sizeof(int) = 4
sizeof(double) = 8
sizeof(char) = 1
sizeof(Fruit) = 32
sizeof(Apple) = 40
Address of Fa[0] = 3DFAD8
Address of Fa[0].no = 3DFAE0
Address of Fa[0].weight = 3DFAE8
Address of Fa[0].key = 3DFAF0
Address of Fa[1] = 3DFAF8
Address of Ab[0] = 3DFA80
Address of Ab[0].no = 3DFA88
Address of Ab[0].weight = 3DFA90
Address of Ab[0].key = 3DFA98
Address of Ab[0].size = 3DFAA0
Address of Ab[0].type = 3DFAA4
Address of Ab[1] = 3DFAA8
请按任意键继续. . .
2. 对象模型图
3. 解析
由于VS本身的原因,vptr和最大成员大小一致(测试了codepad等网络编译器,发现部分编译器vptr都是4B),故vptr占8位。
!! 内存对齐规则:
第一个成员在offset 0的位置,成员依次向下排列。
每个成员放置时的offset位置应是自身大小的倍数。
按此内存对齐规则排列,得到对象模型图,符合测试结果。
测试代码
文件1:Fruit.h
#ifndef __MYFRUIT__
#define __MYFRUIT__
class Fruit
{
private:
int no;
double weight;
char key;
public:
void print() {}
virtual void process() {}
int size_no() { return sizeof(no); }
int size_weight() { return sizeof(weight); }
int size_key() { return sizeof(key); }
int address_no() { return int(&no); }
int address_weight() { return int(&weight); }
int address_key() { return int(&key); }
};
class Apple :public Fruit
{
private:
int size;
char type;
public:
void save() {}
virtual void process() {}
int size_size() { return sizeof(size); }
int size_type() { return sizeof(type); }
int address_size() { return int(&size); }
int address_type() { return int(&type); }
};
#endif
文件2:Fruit-test.cpp
#include <iostream>
#include "Fruit.h"
int main()
{
Fruit Fa[2];
Apple Ab[2];
std::cout << "sizeof(int) = " << sizeof(int) << std::endl;
std::cout << "sizeof(double) = " << sizeof(double) << std::endl;
std::cout << "sizeof(char) = " << sizeof(char) << std::endl;
std::cout << "sizeof(Fruit) = " << sizeof(Fruit) << std::endl;
std::cout << "sizeof(Apple) = " << sizeof(Apple) << std::endl;
// std::cout << "sizeof(long double) = " << sizeof(long double) << std::endl;
(std::cout << std::hex).setf(std::ios::uppercase);
std::cout << "Address of Fa[0] = " << int(&Fa[0]) << std::endl;
std::cout << "Address of Fa[0].no = " << Fa[0].address_no() << std::endl;
std::cout << "Address of Fa[0].weight = " << Fa[0].address_weight() << std::endl;
std::cout << "Address of Fa[0].key = " << Fa[0].address_key() << std::endl;
std::cout << "Address of Fa[1] = " << int(&Fa[1]) << std::endl;
std::cout << "Address of Ab[0] = " << int(&Ab[0]) << std::endl;
std::cout << "Address of Ab[0].no = " << Ab[0].address_no() << std::endl;
std::cout << "Address of Ab[0].weight = " << Ab[0].address_weight() << std::endl;
std::cout << "Address of Ab[0].key = " << Ab[0].address_key() << std::endl;
std::cout << "Address of Ab[0].size = " << Ab[0].address_size() << std::endl;
std::cout << "Address of Ab[0].type = " << Ab[0].address_type() << std::endl;
std::cout << "Address of Ab[1] = " << int(&Ab[1]) << std::endl;
system("pause");
return 0;
}