C++中的对象_纪要(二)

C++对象的内存布局

看以下程序,C++如何存储和实现这个类的对象:
C++中的对象_纪要(二)C++中的对象_纪要(二)View Code

1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 class simpleClass{
 5 public:
 6     static int nCount;        //静态成员数据
 7     int nValue;                //非静态成员数据
 8     char c;
 9 
10     simpleClass(){}
11     virtual ~simpleClass(){}    //虚析构函数
12     int getValue();            //非静态成员函数
13     virtual void foo(void){}    //虚函数
14     static void addCount();    //静态成员函数
15 };
16 int main()
17 {
18     simpleClass aSimple;
19     printf("Object start address:    %xn", &aSimple);
20     printf("nValue address:        %xn",&aSimple.nValue);
21     printf("c address:        %xn",&aSimple.c);
22     printf("size:    %dn", sizeof(simpleClass));
23 
24     return 0;
25 }

执行结果:

C++中的对象_纪要(二)

结果显示通过sizeof()得到的simpleClass的对象是12个字节。

静态数据成员存储在全局/静态存储区中,并不作为对象占据内存的一部分,sizeof()返回的大小不包括nCount所占据的内存的大小。

nValue是整型,大小为4个字节(32位机),c是字符型,大小是1个字节。32位机上,为了提高效率会按4个自己对齐,因此c也占据了4个字节。

这样,simpleClass中的数据成员共占用了8个字节。而simpleClass中还有1个静态成员函数,两个虚函数和两个非静态成员函数,这些函数不会只占用4个字节。

如果修改simpleClass,去掉两个虚函数,此时通过sizeof()得到的simpleClass对象的大小就变成了8个字节,可见剩下的4个字节和虚函数有关。

虚函数是C++中的一个重要特性,用来实现面向对象中的多态性。即只有在程序运行时,才能决定一个父类对象的指针调用的函数是父类还是子类中的实现。为了实现这一特性,C++编译器在碰到含有虚函数的类时,会分配一个指针指向一个函数地址表,叫做“虚函数表”,这4个字节就是虚函数表指针所占据的4个字节。

从以上执行结果中可以看出,虚函数表指针占据的是一个对象开始的4个字节。

对于静态成员函数和非静态成员函数,C++编译器采用与普通C函数类似的方式进行编译,只不过对函数名进行了名称修饰,用来支持重载。并且在参数列表中增加了一个this指针,用来表明是哪一个对象调用的该函数。因此静态成员函数和非静态成员函数的多少对对象的大小没有影响。

结论:

1)非静态数据成员是影响对象占据内存大小的主要因素,随着对象数目的增加,非静态成员占据的内存会相应的增加。

2)所有的对象共享一份静态数据成员,所以静态数据成员占据的内存的数量不会随着对象数据数目的增加而增加。

3)静态成员函数和非静态成员函数不会影响对象内存的大小,虽然其实现会占用相应的内存空间,同样也不会随着对象数据的增加而增加。

4)如果对象中包含虚函数,会增加4个字节的空间,不论有多少个虚函数。

C++中的对象_纪要(二)
原文链接: https://www.cnblogs.com/kkkwar/archive/2012/04/22/2465232.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/48223

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 上午12:04
下一篇 2023年2月9日 上午12:05

相关推荐