我们要知道什么是类的实例化,所谓类的实例化就是在内存中分配一块地址,用sizeof对类名操作,得到的结果是该类的对象在存储器中所占据的字节大小,由于静态成员变量不在对象中存储,因此这个结果等于各非静态数据成员(不包括成员函数)的总和加上编译器额外增加的字节。
确定类大小的几个原则:
1.为类的非静态成员数据的类型大小之和
2.有编译器额外加入的成员变量的大小,用来支持语言的某些特性(如:指向虚函数的指针)
3.为了优化存取效率,进行的边缘调整
4.与类中的构造函数,析构函数以及其他的成员函数无关
非继承:
class A
{
static int num1;
int num2;
char num3;
void fun1(){}
virtual void fun2(){}
virtual void fun3(){}
};
int main()
{
cout << sizeof(A) << endl;
}
输出结果:
sizeof(A) = 4(int) + 4(char对齐) + 4(虚表指针) = 12
分析:
1.static静态成员变量不需计算
2.和求结构体的sizeof是一样的,需要考虑偏移和对齐
3.成员函数不占用对象空间
4.类中定义了虚函数,需要存放一个指向虚表的指针,32位系统中,指针占4个字节
继承:
class A
{
int num1;
virtual void fun1(){}
};
class B : public A
{
int num2;
virtual void fun2(){}
};
int main()
{
cout << sizeof(B) << endl;
}
输出结果:
sizeof(B) = 4(int) + 4(int) + 4(虚表指针) = 12
分析:
虽然子类和父类都包含虚函数, 但它们存放于同一个虚表中,因此只需要一个指针
虚继承:
class A
{
int num1;
virtual void fun1(){}
};
class B : virtual public A
{
int num2;
virtual void fun2(){}
};
int main()
{
cout << sizeof(B) << endl;
}
输出结果:
sizeof(B) = 4(int) + 4(A类虚表指针) + 4(int) + 4(B类虚表指针) + 4(虚继承指针) = 20
分析:
如果子类和基类都有虚函数,各自用各自的虚表