題目描述:1. 分別給出下面的型別Fruit和Apple的型別大小(即物件size),並通過畫出二者物件模型圖以及你的測試來解釋該size的構成原因。
class Fruit{test
int no;
double weight;
char key;
public:
void print() { }
virtual void process(){ }
};
class Apple: public Fruit{
int size;
char type;
public:
void save() { }
virtual void process(){ }
};
當類裡面存在虛擬函式時,這個類所佔的記憶體就會比沒有虛擬函式時候大一點,大的位置是在類的成員變數前面會多出一個指標(vptr),它指向虛指標表(vtbl),虛指標表裡面的每一個指標再指向對應的虛擬函式。從而實現動態繫結。
在資料儲存時,由於記憶體是按照最小塊分配的,且根據c++標準,成員的記憶體順序與程式碼的定義順序相同,且在初始化子類的物件時,會先初始化父類的物件,再初始化子類的物件。
測試程式碼如下:
#include <iostream>
using namespace std;
class Fruit
{
public:
int no=10;
double weight;
char key;
public:
void print(){}
virtual void process(){}
};
class Apple: public Fruit
{
public:
int size;
char type;
public:
void save(){}
virtual void process(){}
};
int main()
{
cout<<"Fruit大小="<<sizeof(Fruit)<<endl;
cout<<"Apple大小="<<sizeof(Apple)<<endl;
cout<<"int 大小="<<sizeof(int)<<endl;
cout<<"double 大小="<<sizeof(double)<<endl;
cout<<"char 大小="<<sizeof(char)<<endl;
Fruit s1;
Apple a1;
cout<<sizeof(s1)<<"-"<<sizeof(a1)<<endl;
cout<<"s1-"<<sizeof(s1) << "-"<<&s1<<endl;
cout<<"s1.no-"<<sizeof(s1.no)<<"-"<<&s1.no<<endl;
cout<<"s1.weight-"<<sizeof(s1.weight)<<"-"<<&s1.weight<<endl;
cout<<"s1.key-"<<sizeof(s1.key)<<"-"<<(void*)&s1.key<<endl;
cout<<"a1.no-"<<sizeof(a1.no)<<"-"<<&a1.no<<endl;
cout<<"a1.weight"<<sizeof(a1.weight)<<"-"<<&a1.weight<<endl;
cout<<"a1.key-"<<sizeof(a1.key)<<"-"<<(void*)&a1.key<<endl;
cout<<"a1.size-"<<sizeof(a1.size)<<"-"<<&a1.size<<endl;
cout<<"a1.type-"<<sizeof(a1.type)<<"-"<<(void*)&a1.type<<endl;
return 0;
}
使用cb編譯器mingw32-gcc-4.7.1的執行結果如下:
二者的物件模型圖如下
由於是32位版本,因此根據執行結果int型別大小為4,double為8,char大小為1.
又由於記憶體對齊原則。其記憶體模型應如下圖所示:
虛擬函式表指標大小與int型別相同為4,32位最小分配記憶體為8,不足8會補足,因此
Fruit大小等於4+4+8+4=20補足8的倍數為24.
Apple大小等於4+4+8+4+4+4=28補足8倍數為32.
使用vs MSBuild執行結果如下:
記憶體圖如下:
vs為64位,所以指標為8位元組因此這種情況下
Fruit大小為 8+8+8+8=32
Apple大小為 8+8+8+8+8=40