一个空类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[];
}; 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 ;
}

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[];
}; 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 ;
}

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[];
}; 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 ;
}

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[];
}; 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 ;
}

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[];
}; 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 ;
}

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[];
}; 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 ;
}

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字节什么也没有。

转自:http://www.cnblogs.com/luxiaoxun/archive/2012/09/01/2666395.html

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

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

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

  2. c++空类的大小

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

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

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

  4. C++类的大小

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

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

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

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

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

  7. sizeof求类的大小

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

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

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

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

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

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

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

随机推荐

  1. requests与urllib 库

    requests库 发送请求: 可以处理所有请求类型:get.post.put.Delete.Head.Options r = requests.get(''https://httpbin.org/' ...

  2. bootstrap里的fileimput的小问题

    fileinput 是bootstrap 里面一个非常好的插件 于是我很开心的开始的使用了 $("#file_upload").fileinput({ uploadUrl: &qu ...

  3. Python学习-day4

    学习装饰器,首先听haifeng老师讲解了一下准备知识. 1.函数即变量 2.高阶函数+嵌套函数==>装饰器 装饰器的作用是在,1)不改变源代码,2)不改变原函数的调用方式的前提下为函数增加新的 ...

  4. 如何用jquery+json来写页面

    以下是json数据表: [ { "p" : "银川市", "c" : [{"c1":"兴庆区"},{ ...

  5. [python学习篇][系统学习][1]python标准库中文、英文网址(一些内建函数,标准库都可以在这里查找)

    http://docspy3zh.readthedocs.io/en/latest/library/   半中文网址 http://usyiyi.cn/translate/python_278/lib ...

  6. [译]PYTHON FUNCTIONS - MAP, FILTER, AND REDUCE

    map, filter, and reduce Python提供了几个函数,使得能够进行函数式编程.这些函数都拥有方便的特性,他们可以能够很方便的用python编写. 函数式编程都是关于表达式的.我们 ...

  7. linux 系统时间调整

    linux的硬件时间是从COMS中读取的. 系统时间是由操作系统维护的. 先查看时区是否正确 (东八区 +8) #date -R 选择时区: #tzselect 修改了系统时间,还应该跟硬件时间进行同 ...

  8. javascript学习笔记 - 引用类型 Array

    二 Array 1.可以通过length属性删除或创建新的数组项 arr = [1,2,3]; arr.length = 4;//增加 [1,2,3,undefined] arr.length = 2 ...

  9. scrapy之spiders

    官方文档:https://docs.scrapy.org/en/latest/topics/spiders.html# 一句话总结:spider是定义爬取的动作(是否跟进新的链接)及分析网页结构(提取 ...

  10. python hashlib模块 logging模块 subprocess模块

    一 hashlib模块 import hashlib md5=hashlib.md5() #可以传参,加盐处理 print(md5) md5.update(b'alex') #update参数必须是b ...