您的位置:首页 > 编程语言 > C语言/C++

C++中类对象的内存空间分配

2018-04-04 08:06 323 查看
一个类,有成员变量:静态与非静态之分;而成员函数有三种:静态的、非静态的、虚的。那么这些个东西在内存中到底是如何分配的呢?#include"iostream"
using namespace std;
class CObject
{
public:
static int a;
CObject();
~CObject();
void Fun();
private:
int m_count;
int m_index;
};

void CObject::Fun()
{
cout << "Fun\n" << endl;
}
CObject::CObject()
{
cout << "Construct!\n";
}
CObject::~CObject()
{
cout << "Destruct!\n";
}

int CObject::a = 1;

void main()
{
cout << "Sizeof(CObject):" << sizeof(CObject) << endl;
cout << "CObject::a=" << CObject::a << endl;
CObject myObject;
cout << "sizeof(myObject):" << sizeof(myObject) << endl;
cout << "sizeof(int)" << sizeof(int) << endl;
}运行结果:
有疑问如下:(1)C++中,应该是对象才会被分配内存空间吧??为什么CObject内存大小是8,刚好和两个成员变量的大小之和一致!难道还没实例化的时候,类就已经有了内存空间了?(2)当对象生成了之后,算出的内存大小怎么还是8,函数难道不占用内存空间吗?至少应该放个函数指针在里面的吧?内存是怎样布局的?(3)静态成员应该是属于类的,怎么类的大小中没有包含静态成员的大小?下面分别解答如下:1)Sizeof(CObject)是在编译时就计算了的,一个类定义了,它所占的内存编译器就已经知道了,这时只是得到它占用的大小,并没有分配内存操作 。2)类的成员函数是不占类内存的,至于你说的函数指针在你的类中有虚函数的时候存在一个虚函数表指针,也就是说如果你的类里有虚函数则sizeof(CObject)的值会增加4个字节。对成员函数(非虚函数)的调用在编译时就确定了。像 myObject.Fun() 这样的调用会被编译成形如 _CObject_Fun( &myObject ) 的样子。函数是不算到sizeof中的,因为函数是代码,被各个对象共用,跟数据处理方式不同。类的属性是指类的数据成员,他们是实例化一个对象时就为数据成员分配内存了,而且每个对象的数据成员是对立的,而成员函数是共有的~静态成员函数与一般成员函数的唯一区别就是没有this指针,因此不能访问非静态数据成员。总之,程序中的所有函数都是位于代码区的。3)静态成员并不属于某个对象,sizeof取的是对象大小。提示:在计算的类的大小时,会有数据对齐的情况发生。因为一个空类也要实例化,所谓类的实例化就是在内存中分配一块地址,每个实例在内存中都有独一无二的地址。同样空类也会被实例化,所以编译器会给空类隐含 的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。
对其进行改动:
结果自然是1220Base类里的int  a;char *p;占8个字节。而虚析构函数virtual ~Base();的指针占4子字节。其他成员函数不归入sizeof统计。Derive类首先要具有Base类的部分,也就是占12字节。int  d;char *p;占8字节static int st;不归入sizeof统计所以一共是20字节。在考虑在Derive里加一个成员char c;?
这个时候,结果就变成了1224一个char c;增加了4字节,说明类的大小也遵守类似class字节对齐,补齐规则。至此,我们可以归纳以下几个原则:1.类的大小为类的非静态成员数据的类型大小之和,也就是说静态成员数据不作考虑。2.普通成员函数与sizeof无关。转载于:http://www.jb51.net/article/101382.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: