sizeof函数对class类操作,其实与对srtuct结构体是一致的(至少目前我没有发现什么不同之处)
这里补充一点关于父类和派生类中的sizeof用处。
//一个简单的父类
class Parent
{
public:
char a;
short b;
};
//一个简单的派生类
class Child:public Parent
{
// 这里其实还加入了父类的一些属性,方法
// ......
public:
int c;
char d;
};
//计算起来跟结构体中包含结构体是一样的。
sizeof(Parent)=4 // ( a _ b b )
sizeof(Child)=12 // ( a _ b b ( c c c c d _ _ _) )
如果父类中有函数,有虚函数,有纯虚函数的话,情况如下:
//含有普通函数的类
class A1
{
void fun(){}
int a;
};
sizeof(A1)=4
//含有虚函数的类
class A2
{
virtual void fun(){}
int a;
};
sizeof(A2)=8
//含有纯虚函数的类
class A3
{
virtual void fun() = 0;
int a;
};
sizeof(A3)=8
//含有两个虚函数的类
class A4
{
virtual void fun(){}
virtual int fun2(){}
};
sizeof(A4)=4;
这里我们会发现一个普通函数是不占内存的,而虚函数和纯虚函数因为有虚表的存在而占用一定的内存。这里可以看一篇其他人写的《C++中虚表深入理解》一文,了解下虚表的作用。
http://blog.youkuaiyun.com/eagleskys/article/details/6308949
这里我大概理解了一下,带有虚函数的类中,会产生一个指向虚表的指针(占4个字节),而且这个指针一直在对象实例的内存首部位置。如果是单一继承的话,每个对象都只有一个虚表;而多重继承后,会为每个有虚函数的类创建一个虚表,虚表的位置按声明位置排列。如下:
//父类1
class Parent1
{
public:
char a;
virtual void fun(){}
short b;
};
sizeof(Parent1)=8
//这里我们观察下Parent1对象内属性的地址
Parent1 p;
cout<<(long)&p<<endl; // 2555506 p的首地址
cout<<(long)&(p.b)<<endl; // 2555510 a的首地址
cout<<(long)&(p.a)<<endl; // 2555512 b的首地址
//父类2
class Parent2
{
public:
virtual void fun2(){}
};
//派生类
class Child:public Parent1,public Parent2
{
};
需要注意的是:在多重继承中,虚表之间不是连在一起的。如果Child中继承自Parent1,而产生的虚表位于0位置的话,那么继承自Parent2而产生的虚表不是在位置4,而是位置8,因为还有一个char和short的位置。虚表相对位于对象实例的首部。
我想差不多就这个意思,如果以后还有什么需要注意再接着记录。