对于sizeof,作个简单的总结:
在一个struct或者class里面定义的一些变量,如果是static类型的,则不算入sizeof计算范围(可能是因为创建对象时,static类型不属于某个特定的对象,而是属于这个类所有的对象,它在内存中不是和对象的变量一起存放的),一般的函数也不算入sizeof计算范围,虚函数则放到一个虚函数表中,有一个虚函数表指针指向这个表格。如果是单继承,则子类的大小是父类的大小加上自己的大小。
在一个struct或者class里面定义的变量,如果要计算其大小,那么首先应该找出类型最大的那个,然后以那个大小来进行“内存对齐”,最后就可以得到真实的大小了。
具体举例如下(部分测试代码来源于:http://blog.csdn.net/fanfanK/article/details/12175585)
#include<iostream>
#include<stdio.h>
using namespace std;
class TwoIntNoVirtual
{
int a;
int b;
void function()
{
cout << "Hello" << endl;
}
};
class TwoIntOneVirtual
{
int a;
int b;
virtual void function()
{
}
};
class TwoIntTwoVirtual
{
int a;
int b;
virtual void function()
{
}
virtual void function2()
{
}
};
class TwoIntOneVirtualDerived : public TwoIntOneVirtual
{
void function2()
{
}
};
class TwoIntTwoVirtualDerived : public TwoIntTwoVirtual
{
void function()
{
}
void function2()
{
}
};
class OtherTest
{
char e, f, g, h, i, j, k;
int a;
int b;
int c;
long long d;
virtual void function() {}
virtual void function2() {}
};
class node0
{
public:
int a;
char b;
short c;
char d;
double e;
};
int main()
{
cout << "TwoIntNoVirtual: " << sizeof(TwoIntNoVirtual) << endl; // 8
cout << "TwoIntOneVirtual: " << sizeof(TwoIntOneVirtual) << endl; // 12
cout << "TwoIntTwoVirtual: " << sizeof(TwoIntTwoVirtual) << endl; // 12
cout << "TwoIntOneVirtualDerived: " << sizeof(TwoIntOneVirtualDerived) << endl; // 12
cout << "TwoIntTwoVirtualDerived: " << sizeof(TwoIntTwoVirtualDerived) << endl; // 12
cout << "OtherTest: " << sizeof(OtherTest) << endl; // 40
cout << "Long long: " << sizeof(short) << endl; // 2
cout << "Long long: " << sizeof(long long) << endl; // 8
cout << "node0: " << sizeof(node0) << endl; // 24
cout << "---------------------" << endl;
node0 no;
cout << "&a = " << (void*)&no.a << endl;
cout << "&b = " << (void*)&no.b << endl;
cout << "&c = " << (void*)&no.c << endl;
cout << "&d = " << (void*)&no.d << endl;
cout << "&e = " << (void*)&no.e << endl;
return 0;
}
在这个例子中,下面这个比较有代表性:
class node0
{
public:
int a;
char b;
short c;
char d;
double e;
};
这里,首先找到大小最大的类型为double,占8个字节,所以应该以8字节的大小来对齐,最后的大小应该是8的整数倍。
现在已经找到最大的为8了,下面就来模拟对上面结构来开内存(以下表格表示内存,地址从上到下、从左到右的方向增加),表格里的字母表示该地址被字母所表示的变量占据着,空格是为了要对齐才这样的。
再分析一个:
class OtherTest
{
char e, f, g, h, i, j, k;
int a;
int b;
int c;
long long d;
virtual void function() {}
virtual void function2() {}
};
这里,也是首先找到大小最大的类型,为long long,在Windows7 32位的VS2013上占8个字节,所以应该以8字节的大小来对齐,最后的大小应该是8的整数倍。
现在已经找到最大的为8了,下面就来模拟对上面结构来开内存(以下表格表示内存,地址从上到下、从左到右的方向增加),表格里的字母表示该地址被字母所表示的变量占据着,空格是为了要对齐才这样的。其中vptr是虚函数表指针,一般占4个字节。
如果是在GCC下,那么sizeof的结果是32,内存如下: