1.一般情况下
代码示例:
#include<iostream>
using namespace std;
class base
{
public:
base()=default;
~base()=default;
private:
static int a;
int b;
char c;
};
int main()
{
base obj;
cout<<sizeof(obj)<<endl;
}
计算结果:8
静态变量a不计算在对象的大小内,由于字节对齐,结果为4+4=8。
2.空类的大小
空类大小为1
代码示例:
#include <iostream>
using namespace std;
class NoMembers
{
};
int main()
{
NoMembers n; // Object of type NoMembers.
cout << "The size of an object of empty class is: "
<< sizeof(n) << endl;
}
输出: The size of an object of empty class is: 1
C++的空类是指这个类不带任何数据,即类中没有非静态(non-static)数据成员变量,没有虚函数
(virtual function),也没有虚基类(virtual base class)。
空类对象不使用任何空间,因为没有任何隶属对象的数据需要存储。然而,C++标准规定,凡是一
个独立的(非附属)对象都必须具有非零大小。换句话说,c++空类的大小不为0
3.含有虚函数成员的类
代码示例:
class Base {
public:
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
};
sizeof(Base)为4,对象中多了一个指向虚函数表的指针,而指针的sizeof是4.
虚函数表存放情况:
每当创建一个包含有虚函数的类或从包含有虚函数的类派生一个类时,编译器就会为这个类创建
一个虚函数表,保存该类所有虚函数的地址。
代码示例:
class Base {
public:
int a;
virtual void f() { cout << "Base::f" << endl; }
virtual void g() { cout << "Base::g" << endl; }
virtual void h() { cout << "Base::h" << endl; }
};
sizeof(Base)为8。
vptr指针的大小为4,又因为对象中还包含一个int变量,字节对齐得4+4=8。
4.多继承下类的大小
代码示例:
#include<iostream>
using namespace std;
class A
{
};
class B
{
char ch;
virtual void func0() { }
};
class C
{
char ch1;
char ch2;
virtual void func() { }
virtual void func1() { }
};
class D: public A, public C
{
int d;
virtual void func() { }
virtual void func1() { }
};
class E: public B, public C
{
int e;
virtual void func0() { }
virtual void func1() { }
};
int main(void)
{
cout<<"A="<<sizeof(A)<<endl; //result=1
cout<<"B="<<sizeof(B)<<endl; //result=16
cout<<"C="<<sizeof(C)<<endl; //result=16
cout<<"D="<<sizeof(D)<<endl; //result=16
cout<<"E="<<sizeof(E)<<endl; //result=32
return 0;
}
结果分析:
-> A为空类,所以大小为1
-> B的大小为char数据成员大小+vptr指针大小。由于字节对齐,大小为4+4=8
-> C的大小为两个char数据成员大小+vptr指针大小。由于字节对齐,大小为4+4=8
-> D为多继承派生类,由于D有数据成员,所以继承空类A时,空类A的大小1字节并没有计入当
中,D继承C,此情况D只需要一个vptr指针,所以大小为数据成员加一个指针大小。由于字节对齐,
大小为8+4=12
-> E为多继承派生类,此情况为我们上面所讲的多重继承,含虚函数覆盖的情况。此时大小计算为
数据成员的大小+2个基类虚函数表指针大小.
5.虚继承的情况
代码示例:
class A {
int a;
};
class B:virtual public A{
virtual void myfunB(){}
};
class C:virtual public A{
virtual void myfunC(){}
};
class D:public B,public C{
virtual void myfunD(){}
};
以上代码中sizeof(A)=4,,sizeof(B)=12,sizeof(C)=12,sizeof(D)=16.
解释:A的大小为int大小加上虚表指针大小。B,C中由于是虚继承因此大小为int大小加指向虚基
类的指针的大小。B,C虽然加入了自己的虚函数,但是虚表指针是和基类共享的,因此不会有自己
的虚表指针,他们两个共用虚基类A的虚表指针。D由于B,C都是虚继承,因此D只包含一个A的副
本,于是D大小就等于int变量的大小+B中的指向虚基类的指针+C中的指向虚基类的指针+一个虚表
指针的大小,由于字节对齐,结果为4+4+4+4=16。