C++类的大小

 

一个空类class A{};的大小为什么是1,因为如果不是1,当定义这个类的对象数组时候A objects[5]; objects[0]和objects[1]就在同一个地址处,就无法区分。

单继承

#include<iostream>
using namespace std;
class A
{
public:
    virtual void aa(){}
private:
    char k[3];
};

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

int main()
{
    cout<<"A's size is "<<sizeof(A)<<endl;
    cout<<"B's size is "<<sizeof(B)<<endl;
    return 0;
}

vs和gcc下
执行结果:A's size is 8
              B's size is 8

说明:有虚函数的类有个virtual table(虚函数表),里面包含了类的所有虚函数,类中有个virtual table pointers,通常成为vptr指向这个virtual table,占用4个字节的大小。成员类B public继承于A,类B的虚函数表里实际上有两个虚函数A::aa()和B::bb(),类B的大小等于char k[3]的大小加上一个指向虚函数表指针vptr的大小,考虑内存对齐为8。

#include<iostream>
using namespace std;
class A
{
public:
    virtual void aa(){}
private:
    char k[3];
};

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

int main()
{
    cout<<"A's size is "<<sizeof(A)<<endl;
    cout<<"B's size is "<<sizeof(B)<<endl;
    return 0;
}

vs和gcc下
执行结果:A's size is 8
              B's size is 8
说明:类B看上去没有虚函数,但实际上它有,只是没有重写,因为public继承,所以有从A继承过来的虚函数A::aa(),实际上类A和类B的虚函数表里的函数都是A::aa()。

#include<iostream>
using namespace std;
class A
{
public:
    virtual void aa(){}
    virtual void aa2(){}
private:
    char k[3];
};

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

int main()
{
    cout<<"A's size is "<<sizeof(A)<<endl;
    cout<<"B's size is "<<sizeof(B)<<endl;
    return 0;
}

vs和gcc下
执行结果:A's size is 8
              B's size is 8

说明:一个类里若有虚函数,无论有多少个虚函数都只有一个指向虚表的指针,虚表中的每一个表项保存着一个虚函数的入口地址。当调用虚函数时,先找到虚表中它对应的表项,找到入口地址再执行。对于直接单继承,无论类B中有无虚函数,由于它继承了类A,且类A里含有虚函数,因此如果类B有虚函数,那么它和类A的是在同一个属于类B的虚表里,这张虚表的虚函数为A::aa()、A::aa2()、B::bb()、B::bb2()。注意:类A里的私有成员在类B里仍占有内存。

多继承

#include<iostream>
using namespace std;
class A
{
public:
    virtual void aa(){}
    virtual void aa2(){}
private:
    char k[3];
};

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

class C: public A,public B
{
public:
    virtual void aa(){} //重写了A的aa()
    virtual void cc(){}
};

int main()
{
    cout<<"A's size is "<<sizeof(A)<<endl;
    cout<<"B's size is "<<sizeof(B)<<endl;
    cout<<"C's size is "<<sizeof(C)<<endl;
    return 0;
}

vs和gcc下
执行结果:A's size is 8
          B's size is 4
          B's size is 12

说明:类A和B的大小就不解释了,参照上面。类C多重继承于A和B(有虚函数覆盖),那么类C的大小是多少?先看成员变量,有一个继承A的char k[3]。再看虚函数,类C的中虚函数是怎么分布的?先有一个虚函数表,里面有继承于类A的虚函数和C自己的虚函数(C::aa(), A::aa2(), C::cc()),如果C没有重写aa(),那么第一个虚函数就是A::aa(),接着有第二张虚函数表是继承包含类B的虚函数B::bb()、B::bb2()(类C没有重写B的虚函数)。总的大小就是2张虚表的大小(也即两个虚函数指针的大小)8字节加上3字节的k[3],考虑内存对齐,就是12字节。

虚继承

#include<iostream>
using namespace std;
class A
{
public:
    virtual void aa(){}
private:
    char k[3];
};

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

int main()
{
    cout<<"A's size is "<<sizeof(A)<<endl;
    cout<<"B's size is "<<sizeof(B)<<endl;
    return 0;
}

vs和gcc下
执行结果:A's size is 8
              B's size is 12
说明:类B里包含,继承的char k[3],继承的虚函数,类B的虚函数表里有A::aa(),因为是虚继承,还有一个指向父类的指针,该指针为指向虚基类的指针(Pointer to virtual base class)。考虑内存对齐,总大小为12。

#include<iostream>
using namespace std;
class A
{
public:
    virtual void aa(){}
private:
    char k[3];
};

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

int main()
{
    cout<<"A's size is "<<sizeof(A)<<endl;
    cout<<"B's size is "<<sizeof(B)<<endl;
    return 0;
}

VS执行结果:A's size is 8
                  B's size is 16

gcc执行结果:A's size is 8
                  B's size is 12

说明:对于虚继承,类B虚继承类A时,首先要通过加入一个指针来指向父类A,该指针被称为虚基类指针。然后包含从父类继承过来的3个char,再加上一个虚函数指针。考虑内存对齐,在gcc下结果是4+4+4=12。在VS下,结果是16,why?这一题和上一题区别只是在类B中添加了一个虚函数,但是两个题目中类B都有虚函数表。在VS下调试查看汇编代码,发现多出来的4字节什么也没有。

关于C++虚函数,可以看《C++虚函数表解析》:http://blog.csdn.net/haoel/article/details/1948051

C++类的大小的更多相关文章

  1. 类的大小——sizeof 的研究

    类的大小——sizeof 的研究(1) 先看一个空的类占多少空间? class Base { public: Base(); ~Base(); }; 注意到我这里显示声明了构造跟析构,但是sizeof ...

  2. c++空类的大小

    初学者在学习面向对象的程序设计语言时,或多或少的都些疑问,我们写的代码与最终生编译成的代码却大相径庭,我们并不知道编译器在后台做了什么工作.这些都是由于我们仅停留在语言层的原因,所谓语言层就是教会我们 ...

  3. C++空类以及没有成员变量的类的大小

    关于C++中空类的大小为1,我们大家都有所了解,但是除了空类之外的其他一些没有成员变量的类的大小,还是有很多不明之处的. 我们来看如下一个例子: #include<iostream> us ...

  4. 关于虚拟继承类的大小问题探索,VC++ 和 G++ 结果是有区别的

    昨天笔试遇到个 关于类占用的空间大小的问题,以前没怎么重视,回来做个试验,还真发现了问题,以后各位笔试考官门,出题时请注明是用什么编译器. vc6/vc8 cl 和 Dev-C 的g++ 来做的测试: ...

  5. C++类对象大小的计算

    (一)常规类大小计算 C++类对象计算需要考虑很多东西,如成员变量大小,内存对齐,是否有虚函数,是否有虚继承等.接下来,我将对此举例说明. 以下内存测试环境为Win7+VS2012,操作系统为32位 ...

  6. sizeof求类的大小

    用sizeof求类的大小,http://blog.csdn.net/szchtx/article/details/10254007(sizeof浅析(三)——求类的大小),这篇博文给出了非常详尽的举例 ...

  7. C++类的大小计算汇总

    C++中类涉及到虚函数成员.静态成员.虚继承.多继承.空类等. 类,作为一种类型定义,是没有大小可言的. 类的大小,指的是类的对象所占的大小.因此,用sizeof对一个类型名操作,得到的是具有该类型实 ...

  8. C++类的大小——sizeof(class)

    第一:空类的大小 class CBase { }; 运行cout<<"sizeof(CBase)="<<sizeof(CBase)<<endl; ...

  9. C++学习笔记(8)----C++类的大小

    C++类的大小 (i) 如下代码: #include<iostream> using namespace std; class CBase { }; class CDerive :publ ...

随机推荐

  1. oracle linux下oracle 10g启动EM、isqlplus及相关命令语法

    转载:http://hancang2000.blog.sohu.com/139239421.html ORACLE_HOME/bin/emctl start dbconsole $ORACLE_HOM ...

  2. 0基础学习ios开发笔记第一天

    Ios操作 界面操作 快捷键 command + c 复制 command+v 粘贴 command +a 全选 command +s 保存 command +z 撤销 command +x  剪切 ...

  3. iOS10---新特性以及适配点(转)

    iOS 10 新特性以及适配点 SiriKit 所有第三方应用都可以用Siri,支持音频.视频.消息发送接收.搜索照片.预订行程.管理锻炼等 Proactive Suggestions 系统预先建议 ...

  4. iOS 高级开发 runtime(三)

    三 .动态添加方法 我们可以通过runtime动态地添加方法.那么到底啥叫动态添加方法呢?动态添加方法就是当我们程序运行时才知道我们应该调用哪个方法.我们首先需要了解这一点,当我们编写完一段代码后,我 ...

  5. bzoj1697:[Usaco2007 Feb]Cow Sorting牛排序 & bzoj1119:[POI2009]SLO

    思路:以bzoj1119为例,题目已经给出了置换,而每一次交换的代价是交换二者的权值之和,而置换一定是会产生一些环的,这样就可以只用环内某一个元素去置换而使得其余所有元素均在正确的位置上,显然要选择环 ...

  6. Android清空画布

    public void clear() { Paint paint = new Paint(); paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR ...

  7. Lambda Expression In Java

     题记在阅读JDK源码java.util.Collections的时候在UnmodifiableCollection类中看到了这么一段代码: public void forEach(Consumer& ...

  8. linux 下串口的配置

    串口最基本的设置包括波特率 校验位 和停止位. 主要是设置个结构体的成员值, #include <termios.h> struct termio { unsigned short c_i ...

  9. 关于angular 自定义directive

    关于angular 自定义directive的小结 首先我们创建一个名为"expander"的自定义directive指令: angular.module("myApp& ...

  10. [GUIDE] How to install Scipy in Maya Windows 64 bit - Google 网上论坛 - Google Chrome

    I've seen a lot of queries about getting scipy working in Maya (Windows 64 bit) with a few not 100% ...