C++对象的内存模型

来源:互联网 发布:淘宝客怎么注册不了了 编辑:程序博客网 时间:2024/06/05 20:29

【学习于C语言中文网,请勿转载】

类是创建对象的模板,不占用内存空间,不存在于编译后的可执行文件中;而对象是实实在在的数据,需要内存来存储。对象被创建时会在栈区或者堆区分配内存。

直观的认识是,如果创建了 10 个对象,就要分别为这 10 个对象的成员变量和成员函数分配内存,如下图所示:


不同对象的成员变量的值可能不同,需要单独分配内存来存储。但是不同对象的成员函数的代码是一样的,上面的内存模型保存了 10 分相同的代码片段,浪费了不少空间,可以将这些代码片段压缩成一份。

事实上编译器也是这样做的,编译器会将成员变量和成员函数分开存储:分别为每个对象的成员变量分配内存,但是所有对象都共享同一段函数代码。如下图所示:

成员变量在堆区或栈区分配内存,成员函数在代码区分配内存。

【示例】使用 sizeof 获取对象所占内存的大小:
  1. #include <iostream>
  2. using namespace std;
  3. class Student{
  4. private:
  5. char *m_name;
  6. int m_age;
  7. float m_score;
  8. public:
  9. void setname(char *name);
  10. void setage(int age);
  11. void setscore(float score);
  12. void show();
  13. };
  14. void Student::setname(char *name){
  15. m_name = name;
  16. }
  17. void Student::setage(int age){
  18. m_age = age;
  19. }
  20. void Student::setscore(float score){
  21. m_score = score;
  22. }
  23. void Student::show(){
  24. cout<<m_name<<"的年龄是"<<m_age<<",成绩是"<<m_score<<endl;
  25. }
  26. int main(){
  27. //在栈上创建对象
  28. Student stu;
  29. cout<<sizeof(stu)<<endl;
  30. //在堆上创建对象
  31. Student *pstu = new Student();
  32. cout<<sizeof(*pstu)<<endl;
  33. //类的大小
  34. cout<<sizeof(Student)<<endl;
  35. return 0;
  36. }
运行结果:
12
12
12

Student 类包含三个成员变量,它们的类型分别是 char *、int、float,都占用 4 个字节的内存,加起来共占用 12 个字节的内存。通过 sizeof 求得的结果等于 12,恰好说明对象所占用的内存仅仅包含了成员变量。

类可以看做是一种复杂的数据类型,也可以使用 sizeof 求得该类型的大小。从运行结果可以看出,在计算类这种类型的大小时,只计算了成员变量的大小,并没有把成员函数也包含在内。

对象的大小只受成员变量的影响,和成员函数没有关系。

假设 stu 的起始地址为 0X1000,那么该对象的内存分布如下图所示:


m_name、m_age、m_score 按照声明的顺序依次排列,和结构体非常类似,也会有内存对齐的问题。

原创粉丝点击