深入分析C++中类的大小

 更新时间:2013年05月04日 09:20:40   作者:  
本篇文章深入分析了C++中类的大小问题。需要的朋友参考下

首先看一个例子:

复制代码 代码如下:

#include <iostream>
 using namespace std;

 class A{};

 class B
 {
     int b;
     char c;
 };

 class C
 {
     int c1;   
     static int c2;
 };
 int C::c2 = 1;

 class D:public C,public B{
     int d;
 };
 int main()
 {
     cout<<"sizeof(A)="<<sizeof(A)<<endl;
     cout<<"sizeof(B)="<<sizeof(B)<<endl;
     cout<<"sizeof(C)="<<sizeof(C)<<endl;
     cout<<"sizeof(D)="<<sizeof(D)<<endl;

     return 0;
 }

运行结果为:

sizeof(A)=1

sizeof(B)=8

sizeof(C)=4

sizeof(D)=16


对于类A来说,虽然A是一个空类,但为了便于空类进行实例化,编译器往往会给它分配一个字节,这样A实例化后便在内存中有了一个独一无二的地址.对于类B,B的大小应为sizeof(int)+sizeof(char)=5,但是考虑内存对齐,B的大小应为8.对于类C,类的静态成员变量被放在全局区,和类的普通成员并没有放在一块。类的静态成员被声明后就已存在,而非静态成员只有类被实例化后才存在。所以C的大小为sizeof(int)=4。D的大小为B+C的大小+自身数据成员的大小,一共为16.

 

==========================分割线在这里====================================

下面讨论含有虚函数的类的大小:

复制代码 代码如下:

#include <iostream>
 using namespace std;

 class A
 {
 public:
     void virtual aa(){};
 };

 class B:public A
 {
     void virtual bb(){};
 };

 class C:virtual A
 {
 public:
     void virtual aa(){};
     void cc(){};
 };

 class D:virtual A
 {
 public:
     void virtual dd(){};
 };

 int main()
 {
     cout<<"sizeof(A)="<<sizeof(A)<<endl;
     cout<<"sizeof(B)="<<sizeof(B)<<endl;
     cout<<"sizeof(C)="<<sizeof(C)<<endl;
     cout<<"sizeof(D)="<<sizeof(D)<<endl;

     return 0;
 }

运行结果为:

sizeof(A)=4

sizeof(B)=4

sizeof(C)=8

sizeof(D)=12

对于class A,它含有一个虚函数,编译器会为虚函数生成一张虚函数表,来记录对应的函数地址,为此,在class A的内存地址中要有一个vfptr_A指针指向这个虚表,所以class A的大小为指针大小,即4.(注意,无论类中有多少个虚函数,它们的大小都是4,因为内存中只需要保存这个指针即可)。

对于class B,它是public继承A,虽然它也有一个虚函数,但是从结果看,B应该和A都在B的vtable(虚表中),所以class B的大小为4.

对于class C,它是vitual 继承A,所以要有一个指向父类A的指针,占有4字节大小aa()是继承自class A的虚函数,从结果来看,它没有在内存中占有空间,所以C的大小为sizeof(A)+4=8.

对于class D,它是虚继承class A,同上,要有一个指向父类A的指针,同时,class D中有虚函数,所以要有一个指向虚表的指针,所以sizeof(D)=sizeof(A)+4+4=12

相关文章

  • 浅谈Windows系统下C语言编程中Glib库的使用

    浅谈Windows系统下C语言编程中Glib库的使用

    这篇文章主要介绍了Windows系统下C语言编程中Glib库的使用,Glib库在多线程编程中经常可以用到,需要的朋友可以参考下
    2016-02-02
  • C++利用easyx图形库实现创意天天酷跑小游戏

    C++利用easyx图形库实现创意天天酷跑小游戏

    这篇文章主要为大家详细介绍了C++如何利用easyx图形库实现创意小游戏——天天酷跑,文中的示例代码讲解详细,快跟随小编一起了解一下吧
    2023-03-03
  • 深入单链表的快速排序详解

    深入单链表的快速排序详解

    本篇文章是对单链表的快速排序进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++超详细讲解操作符的重载

    C++超详细讲解操作符的重载

    C++预定义中的运算符的操作对象只局限于基本的内置数据类型,但是对于我们自定义的类型(类)是没有办法操作的。但是大多时候我们需要对我们定义的类型进行类似的运算,这个时候就需要我们对这么运算符进行重新定义,赋予其新的功能,以满足自身的需求
    2022-06-06
  • C/C++ ip地址与int类型的转换实例详解

    C/C++ ip地址与int类型的转换实例详解

    这篇文章主要介绍了C/C++ ip地址与int类型的转换实例详解的相关资料,这里提供了实例代码,实现思路及实现方法,需要的朋友可以参考下
    2016-12-12
  • C++动态规划之最长公子序列实例

    C++动态规划之最长公子序列实例

    这篇文章主要介绍了C++动态规划之最长公子序列,实例分析了C++求最长公子序列的相关技巧,是C++字符串操作的一个典型应用,需要的朋友可以参考下
    2015-04-04
  • C语言中各种操作符的详细介绍(纯干货!)

    C语言中各种操作符的详细介绍(纯干货!)

    指令系统的每一条指令都有一个操作符,它表示该指令应进行什么样性质的操作,不同的指令用操作符这个字段的不同编码来表示,每个编码代表一种指令,这篇文章主要给大家介绍了关于C语言中操作符的相关资料,需要的朋友可以参考下
    2021-06-06
  • C++inline函数的特性你了解吗

    C++inline函数的特性你了解吗

    这篇文章主要为大家详细介绍了C++的inline函数,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C语言实现电子邮件地址验证程序

    C语言实现电子邮件地址验证程序

    这篇文章主要介绍了C语言实现电子邮件地址验证程序,利用的是POSIX正则表达式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2015-11-11
  • C++类与对象之运算符重载详解

    C++类与对象之运算符重载详解

    运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的
    2021-10-10

最新评论