浅谈C++ 类的实例中 内存分配详解

2020-01-06 16:39:39丽君

一个类,有成员变量:静态与非静态之分;而成员函数有三种:静态的、非静态的、虚的。

那么这些个东西在内存中到底是如何分配的呢?

以一个例子来说明:


#include"iostream.h"
class CObject
{
public:
  static int a;
  CObject();
  ~CObject();
  void Fun();
private: 
int m_count; 
int m_index;
};
VoidCObject::Fun(){  cout<<"Funn"<<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;
}

 这是我的一段测试代码, 运行结果是:

 


Sizeof(CObject):8
CObject::a=1
Construct!
sizeof(myObject):8
sizeof(int)4
Destruct!

 我有疑问如下:

(1)C++中,应该是对象才会被分配内存空间吧??为什么CObject内存大小是8,刚好和两个成员变量的大小之和一致!难道还没实例化的时候,类就已经有了内存空间了?

(2)当对象生成了之后,算出的内存大小怎么还是8,函数难道不占用内存空间吗?至少应该放个函数指针在里面的吧?内存是怎样布局的?

(3)静态成员应该是属于类的,怎么类的大小中没有包含静态成员的大小?

下面分别解答如下:

1)Sizeof(CObject)是在编译时就计算了的,一个类定义了,它所占的内存编译器就已经知道了,这时只是得到它占用的大小,并没有分配内存操作 。也可以这样想:编译器肯定知道大小了,这与分配内存空间无关,知道大小了,以后实例化了才能知道要分配多大。

2)类的普通成员、静态成员函数是不占类内存的,至于你说的函数指针在你的类中有虚函数的时候存在一个虚函数表指针,也就是说如果你的类里有虚函数则sizeof(CObject)的值会增加4个字节。

其实类的成员函数实际上与普通的全局函数一样。

只不过编译器在编译的时候,会在成员函数上加一个参数,传入这个对象的指针。

成员函数地址是全局已知的,对象的内存空间里根本无须保存成员函数地址。

对成员函数(非虚函数)的调用在编译时就确定了。

像 myObject.Fun() 这样的调用会被编译成形如 _CObject_Fun( &myObject ) 的样子。

函数是不算到sizeof中的,因为函数是代码,被各个对象共用,跟数据处理方式不同。对象中不必有函数指针,因为对象没必要知道它的各个函数的地址(调用函数的是其他代码而不是该对象)。