1:先看一个空类的大小:
#include <iostream>
using namespace std;
class A
{
};
int main(int argc, char** argv) {
cout<<sizeof(A)<<endl;
return 0;
}
sizeof(A)的结果为1;
#include <iostream>
using namespace std;
class A
{
public:
A();
~A();
};
int main(int argc, char** argv) {
cout<<sizeof(A)<<endl;
return 0;
}
sizeof(A)的结果照样为1;
首先,说类的大小本质上是说类的实例的大小,类只是一个类型定义,它是没有大小可言的,用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小;
calss A; A a; szieof(A) == sizeof(a);但是这样编译在编译器当中编译不通过。
上面为什么sizeof(A)的结果为1呢?
(1)因为一个空类也要实例化,所谓类的实例化就是在内存中分配一块地址,每个实例在内存当中都有独一无二的地址。同样空类也要被实例化,所以编译器会给空类
添加一个隐含的字节,这样空类实例化后就有了独一无二的地址了。
(2)而析构函数,跟构造函数这些成员函数,是跟sizeof无关的,也不难理解因为我们的sizeof是针对实例,而普通成员函数,是针对类体的,一个类的成员函数,多个实例也
用相同的函数指针,所以自然不能归为实例的大小。
带参数类型的大小:
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
class A{
public:
int a;
A()
{
}
~A()
{
}
};
int main(int argc, char** argv) {
A a;
cout<<sizeof(A)<<endl;
return 0;
}
sizeof(A) = 4;
带静态类型参数的大小:
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
class A{
public:
static int a;
A()
{
}
~A()
{
}
};
int main(int argc, char** argv) {
A a;
cout<<sizeof(A)<<endl;
return 0;
}
sizeof(A) = 1;
类的静态数据成员被编译器放在程序的一个global data members中,它是类的一个数据成员.但是它不影响类的大小,不管这个类实际产生了多少实例,还是派生了多少新的类,静态成员数据在类中永远只有一个实体存在,而类的非静态数据成员只有被实例化的时候,他们才存在.但是类的静态数据成员一旦被声明,无论类是否被实例化,它都已存在.可以这么说,类的静态数据成员是一种特殊的全局变量.
带一个虚函数类型的大小:
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
class A{
public:
A()
{
}
virtual ~A()
{
}
};
int main(int argc, char** argv) {
A a;
cout<<sizeof(A)<<endl;
return 0;
}
sizeof(A) = 4;
带多个虚函数的大小
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
class A{
public:
A()
{
}
virtual void fun()
{
}
virtual ~A()
{
}
};
int main(int argc, char** argv) {
A a;
cout<<sizeof(A)<<endl;
return 0;
}
sizeof(A) = 4;
如果在类中声明了虚函数(不管是1个还是多个),那么在实例化对象时,编译器会自动在对象里安插一个指针指向虚函数表VTable,在32位机器上,一个对象会增加4个字节来存储此指针,它是实现面向对象中多态的关键。而虚函数本身和其他成员函数一样,是不占用对象的空间的.
再看下面一段代码:
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
class A{
};
class B{
char c;
};
class C{
char a;
char b;
virtual ~C()
{
}
};
class D{
int a;
void fun()
{
int m;
}
};
int main(int argc, char** argv) {
cout<<sizeof(A)<<endl; //1
cout<<sizeof(B)<<endl; //1
cout<<sizeof(C)<<endl; //8
cout<<sizeof(D)<<endl; //4
return 0;
}
输出 1 1 8 4;
结合这个实例 我们可以得出以下结论:
在一个类中,普通成员函数,构造函数,析构函数,所有的虚函数,以及静态成员变量都是不占用类对象的内存空间的。
一个类对象的大小 等于 VPTR(虚函数指针)+ 非静态数据成员变量 + 内存对其时候的扩展内存大小!
继承的类的大小:
<span style="color:#000000;">#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
class A{
static int a;
};
class B : public A
{
public:
virtual int getNun()
{
return 10;
}
private:
char* p;
};
class C: public B
{
public:
int getNum()
{
return 3;
}
B b;
};
int main(int argc, char** argv) {
cout<<sizeof(A)<<endl; //1
cout<<sizeof(B)<<endl; //8
cout<<sizeof(C)<<endl; //16
return 0;
}</span>
1.类的大小为类的非静态成员数据的类型大小之和,也就是说静态成员数据不作考虑。
2.普通成员函数与sizeof无关。
3.虚函数由于要维护在虚函数表,所以要占据一个指针大小,也就是4字节。
4.类的总大小也遵守类似class字节对齐的,调整规则