1. 空类
#include <iostream>
using namespace std;
class Base
{
};
int main()
{
cout<<sizeof(Base)<<endl;
return 0;
}
输出:1
因为一个空类也要实例化,所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。
2. 添加一个构造函数和析构函数
#include <iostream>
using namespace std;
class Base
{
public:
Base();
~Base();
};
int main()
{
cout<<sizeof(Base)<<endl;
return 0;
}
输出:1
调用构造函数和析构函数只需要知道函数的地址即可,而这些函数的地址只与类型相关,而与类型的实例无关。
3. 将析构函数标记为虚函数
#include <iostream>
using namespace std;
class Base
{
public:
Base();
virtual ~Base();
};
int main()
{
cout<<sizeof(Base)<<endl;
return 0;
}
输出:4
编译器一旦发现一个类型中有虚函数,就会为该类型生成虚函数表,并在该类型的每一个实例中添加一个指向虚函数表的指针。 32位机器上为4字节,64位机器上为8字节。
4. 派生类的大小,含static型变量
#include <iostream>
using namespace std;
class Base
{
public:
Base();
virtual ~Base(); //每个实例都有虚函数表
void set_num(int num) //普通成员函数,为各实例公有,不归入sizeof统计
{
a=num;
}
private:
int a; //占4字节
char *p; //4字节指针
};
class Derive:public Base
{
public:
Derive():Base(){};
~Derive(){};
private:
static int st; //非实例独占
int d; //占4字节
char *p; //4字节指针
};
int main()
{
cout<<sizeof(Base)<<endl;
cout<<sizeof(Derive)<<endl;
return 0;
}
输出:12
20
Base类里的int a;char *p;占8个字节。而虚析构函数virtual ~Base();的指针占4子字节。其他成员函数不归入sizeof统计。
Derive类首先要具有Base类的部分,也就是占12字节。int d;char *p;占8字节
static int st;不归入sizeof统计,所以一共是20字节。