c++中最重要的就是类,那么给你一个类的对象,你知道它在内存中如何存储的吗?它占内存中多少个字节?

首先确定类的构成:

1,数据成员:可以是内置类型,类类型。

2,函数成员:虚函数,非虚函数

1)数据成员

内置类型对齐原则

内置类型就是常用的:char,short,long,int,float,double.

这些内置类型在类的对象中对齐方式,字节为单位(在c中结构体也是一样的)

char          1

short          2

long            4

int            4

float            4

fouble        8

类类型对齐原则(c中就是结构体对齐原则)

取类中最长的数据成员作为对齐原则。例如,类中最长为double,那么就是8个字节。

2)函数成员

函数成员是不占用内存中类的对象的字节。为什么呢,你可以这样理解,c++中为了兼容c也允许struct作为类的声明。在c中struct是用来声明结构体类型的,只不过c中的结构体没有函数成员。

同样c++中允许的函数成员,只不过是类给函数提供了一个作用域。

一个对象调用函数的时候,可以等价为普通函数的调用

例如:

struct A

{

void f(){cout<<x<<endl;};

int x;

};

A a;

a.f();

a.f()等价于调用f(&a);类中的成员函数(static成员函数除外)形参中都有个隐含的this指针,它指向类对象本身。

当对象a调用f()的时候,它会把a的地址传给this指针,所以f()就等价执行

f(const A* this)

{

cout<<this->x<<endl;

}

所以对象中并不需要保存函数成员。

下面举个例子说明类对象的字节数

1,

class A

{

char c;

int i;

};

A a;

这对象a的内存大小sizeof(a)=8(字节为单位)

解释下:

c放在起始位置0,占1个字节。

i是int要4字节对齐,所以前面要空3字节。它要从位置4开始存储,占4,5,6,7四个位置。

最后类要按照他最长的数据成员对齐,就是i也就是4字节对齐.因为已经占用了8个字节,8是对齐4的,所以不用额外增加字节数了。最后sizeof(a)=8。

2,

class B

{

doube d;

char c;

A a;//1中的类类型A

};

B b;

这对象b的内存大小sizeof(b)=24(字节为单位)

解释:

d放在起始位置0到7,占8个字节。

c是char要1字节对齐,所以放在位置8,占1个字节。

b是类类型,在1中可以知道它是8字节对齐的,所以前面要空7个字节,它从位置16开始存储,一直到23,占8个字节。

最后类要按照他最长的数据成员对齐,就是d也就是8字节对齐,因为已经占用了24个字节,24是对齐8的,所以不用额外增加字节数了。最后sizeof(a)=24。

3,

class c

{

char c;

int i1;

double d;

int i2;

};

C c;

你知道sizeof(c)=多少吗? 答案:24.不解释了~。(注意这个最后需要额外增加空间来对齐类)

上面讲的,你同样可以使用c中的结构体类型变量的字节数计算。

下面说下特殊的,就是c中没有的。

1,类中有虚函数的时候

我们在一开始的时候,就说了成员函数中有虚函数。c++为了处理多态,所以引入虚函数,在一个类对象存储空间中,第一个位置需要4个字节来存储一个指针。这个指针是指向改类的虚函数表的。也就是这个指针的值就是改类的虚函数表的地址。所以就比上面说的多了4个字节。

例如:

class D

{

public:

virtual void f(){};

double d;

}

D d;

sizeof(d)=16;

2,派生类内存大小

例如:

class E:D

{

int d0;

char c;

int d1;

};

E e;

sizeof(e)=32;

解释:

基类中有虚函数,所以派生类对象一开始要4个字节存储指向虚函数表的指针。

然后继承D中的数据成员double d;

它要8字节对齐,所以前面空4个字节。

下面就开始存储d0,c,d1.最后类对齐可计算得到32.

C++类的存储(部分可用与c的结构体)的更多相关文章

  1. swift学习笔记3——类、结构体、枚举

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  2. 5.Swift枚举|结构体|类|属性|方法|下标脚本|继承

    1. 枚举: ->在Swift中依然适用整数来标示枚举值,需搭配case关键字 enum  Celebrity{  case DongXie,XiDu,Nandi,BeiGai }  // 从左 ...

  3. 全面总结sizeof的用法(定义、语法、指针变量、数组、结构体、类、联合体、位域位段)

    一.前言 编译环境是vs2010(32位). <span style="font-size:18px;">#include<iostream> #inclu ...

  4. 【Swift学习】Swift编程之旅---类和结构体(十三)

    与其他编程语言所不同的是,Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件.你所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口. 注意:通常一个类 ...

  5. C#中的结构体与类的区别

    经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字class 定义结构使用关键字str ...

  6. Swift枚举|结构体|类|属性|方法|下标脚本|继承

    1. 枚举: ->在Swift中依然适用整数来标示枚举值,需搭配case关键字 enum  Celebrity{  case DongXie,XiDu,Nandi,BeiGai }  // 从左 ...

  7. Swift: 类与结构体

    对比类与结构体 类与结构体有许多的相同点,它们都可以: 定义属性来存储值: 定义方法来提供功能: 定义下标操作: 定义初始化函数: 扩展它的默认的实现: 遵从协议: 类有一些额外的能力,但是结构体没有 ...

  8. swift 学习- 10 -- 类和结构体

    // '类和结构体' 是人们构建代码所使用的一种通用且灵活的构造体, 我们可以使用完全相同的语法规则来为 '类和结构体' 定义属性 (变量 和 常量) 和添加方法, 从而扩展 类和结构体 的功能 // ...

  9. 浅析C#中的结构体和类

    类和结构是 .NET Framework 中的常规类型系统的两种基本构造. 两者在本质上都属于数据结构.封装着一组总体作为一个逻辑单位的数据和行为. 数据和行为是该类或结构的"成员" ...

随机推荐

  1. ARP及RARP简介

    1.概念 ARP(Address Resolution Protocol) 地址解析协议 RARP(Reverse Address Resolution Protocol) 反向地址解析协议 2.AR ...

  2. 转:利用ant与jmeter实现负载测试自动化

    性能测试一直以来都是测试领域一个令人争议的话题.测试的参考标准.评判依据及测试的方法选择都很难有一个统一的说法.但无论如何,对于需要能够承受一定压力而运行的程序来说,进行其进行功能和性能测试是一个必不 ...

  3. 笔记整理--Linux编程

    linux c编程open() read() write()函数的使用方法及实例 | 奶牛博客 - Google Chrome (2013/8/31 17:56:10) 今天把文件IO操作的一些东东整 ...

  4. Base64笔记

    1. 昨天的<MIME笔记>中提到,MIME主要使用两种编码转换方式----Quoted-printable和Base64----将8位的非英语字符转化为7位的ASCII字符. 虽然这样的 ...

  5. jq中的evet.target

    1.this和event.target的区别: js中事件是会冒泡的,所以this是可以变化的,但event.target不会变化,它永远是直接接受事件的目标DOM元素: 2.this和event.t ...

  6. 转 spring security的使用

    [转自:http://haohaoxuexi.iteye.com/blog/2154714] 关于登录 目录 1.1     form-login元素介绍 1.1.1    使用自定义登录页面 1.1 ...

  7. 고 보니: 做完A发现新的事实B

    1. 선생님 얘기를 듣고 보니 이제 이해가 되네요. 2. 막상 옷을 입고 보니 꽤 잘 어우리는 것 같았다. 不能用于过去式 다 보니和 고 보니区别 다 보니: 表示在做某事过程中发现某状 ...

  8. ZOJ 3939The Lucky Week<模拟/暴力>

    题意:我们认为日期的天数为1,11,21,并且是周一的为Lucky Week;现在给出第一个lucky week的日期,求第N个的lucky week: //1:四百年一轮回,从闰年和平年的判定可以推 ...

  9. mr本地运行的几种模式

    MR程序的几种提交运行模式 本地模型运行 1/在windows的eclipse里面直接运行main方法,就会将job提交给本地执行器localjobrunner执行 ----输入输出数据可以放在本地路 ...

  10. Ubuntu 14.04 使用MyEclipse 10.7 闪退解决

    http://www.linuxidc.com/Linux/2014-05/101750.htm