c语言格式对齐填充_C ++中类的大小 课堂上的填充和对齐| 派生类的大小

c语言格式对齐填充

Prerequisite:

先决条件:

  • sizeof() operator in C/C++

    C / C ++中的sizeof()运算符

  • Size of struct in C

    C中的struct大小

We know that a struct size is not only the summation of all the data members, rather it's the minimum sum guaranteed. The compiler adds some padding for data member alignment.

我们知道,结构大小不仅是所有数据成员的总和,而且是保证的最小总和。 编译器为数据成员对齐添加了一些填充。

In the C++ class, things are exactly the same as a struct. But there are a few more things.

在C ++类中,事物与结构完全相同。 但是还有更多的事情。

Firstly, while in C++ there are member functions, static data members. Do those have any contribution to the size of the class, objects?

首先,在C ++中有成员函数,即静态数据成员。 这些对类,对象的大小有贡献吗?

The answer is no. Only the non-static data members contribute to the size of class and objects. This is because static members have only one instance which is shared among all objects. And normal member functions are like executable code which does not have size like data members.

答案是不。 只有非静态数据成员才有助于类和对象的大小。 这是因为静态成员只有一个实例,该实例在所有对象之间共享。 普通成员函数就像可执行代码,没有像数据成员那样大小。

Like in the following class,

像下面的课一样

class A {
private:
static int i;
int a;
char b;
public:
A()
{
a = 0;
b = '#';
}
A(int aa, char bb)
{
a = aa;
b = bb;
}
int get_int()
{
cout << a << endl;
return a;
}
char get_char()
{
cout << b << endl;
return b;
}
};

Size of the class should be sum of all the non-static data member+ padding, which is like below:

类的大小应为所有非静态数据成员+填充的总和,如下所示:

C++ | size of a class (1)

Above is the alignment of class A and that's why the size of the class is 8 Bytes. Static data members and member functions have no contribution.

上面是A类的对齐方式,这就是为什么该类大小为8 Bytes的原因 。 静态数据成员和成员函数没有贡献。

编译器如何添加填充? (How compiler adds padding?)

Now the question is how compiler adds padding and align? The method is compiler dependent and kind of greedy. It aligns till the boundary of maximum memory allocated.

现在的问题是编译器如何添加填充和对齐? 该方法取决于编译器并且有点贪婪。 对齐直到分配的最大内存边界。

Here we find that max memory allocated is 8 Bytes, thus all the data members acquire 8 Bytes and the total size is 32 Bytes. Now the question is will it happen every time similarly?

在这里,我们发现分配的最大内存为8字节,因此所有数据成员都获取8字节,总大小为32字节。 现在的问题是,是否每次都会同样发生?

Is it like the number of data members * max datatype size?

就像数据成员数*最大数据类型大小一样吗?

The answer is no. It will try to align optimally keeping the same order. To check an example please follow the article on structure size in C. Also, later in this article, we have instances of such.

答案是不。 它将尝试最佳对齐以保持相同顺序。 要查看示例,请阅读有关C语言中结构大小的文章。此外,在本文的稍后部分,我们将提供这样的实例。

派生类的大小 (Size of a derived class)

What is the size of a derived class? Of course, a derived class has all data members of the base class it inherits and does it has its own copied of those data members too. Thus size should be the size of base class data members + size of derived class data members.

派生类的大小是多少? 当然,派生类具有其继承的基类的所有数据成员,并且它也具有这些数据成员的自己的副本。 因此,大小应为基类数据成员的大小+派生类数据成员的大小。

Let's check the below code and the output.

让我们检查以下代码和输出。

In the above structure, we find that the size is 24 Bytes though the same data members have been used. This is due to the change in the order of the member declaration. In this case, the alignment and padding would be like below:

在上面的结构中,我们发现尽管使用了相同的数据成员,但大小为24字节。 这是由于成员声明顺序的更改。 在这种情况下,对齐方式和填充将如下所示:

#include <bits/stdc++.h>
using namespace std;
class Base {
protected:
static int i;
int a;
char b;
public:
Base()
{
a = 0;
b = '#';
}
Base(int aa, char bb)
{
a = aa;
b = bb;
}
int get_int()
{
cout << a << endl;
return a;
}
char get_char()
{
cout << b << endl;
return b;
}
};
class Derived : public Base {
private:
int c;
char d;
public:
Derived()
{
c = 0;
d = '#';
}
Derived(int cc, char dd)
{
c = cc;
d = dd;
}
int get_int()
{
cout << c << endl;
return c;
}
char get_char()
{
cout << d << endl;
return d;
}
};
int main()
{
Base b;
Derived d;
printf("Size of class Base: %lu\n", sizeof(Base));
printf("Size of object b: %lu\n", sizeof(b));
printf("Size of class Derived: %lu\n", sizeof(Derived));
printf("Size of object d: %lu\n", sizeof(d));
return 0;
}

Output:

输出:

Size of class Base: 8
Size of object b: 8
Size of class Derived: 16
Size of object d: 16

So here the size of the base class object is 8 bytes, whereas the size of the derived class object is 16 Bytes.

因此,这里的基类对象的大小为8个字节,而派生类对象的大小为16个字节。

For the base class it's similar like below:

对于基类,它类似于以下内容:

C++ | size of a class (2)

While for the derived class it's like:

而对于派生类,它就像:

C++ | size of a class (3)

So the thing is the order of data members are being maintained. And since we know that the base class constructor is invoked first, that's why the base class members come first.

因此,关键是要维护数据成员的顺序。 而且由于我们知道首先调用基类构造函数,所以这就是基类成员首先出现的原因。

Now let's change the order of data member in the derived class and check the size of the class & object.

现在,让我们更改派生类中数据成员的顺序,并检查类和对象的大小。

#include <bits/stdc++.h>
using namespace std;
class Base {
protected:
static int i;
int a;
char b;
public:
Base()
{
a = 0;
b = '#';
}
Base(int aa, char bb)
{
a = aa;
b = bb;
}
int get_int()
{
cout << a << endl;
return a;
}
char get_char()
{
cout << b << endl;
return b;
}
};
class Derived : public Base {
private:
char d;
int c;
public:
Derived()
{
c = 0;
d = '#';
}
Derived(int cc, char dd)
{
c = cc;
d = dd;
}
int get_int()
{
cout << c << endl;
return c;
}
char get_char()
{
cout << d << endl;
return d;
}
};
int main()
{
Base b;
Derived d;
printf("Size of class Base: %lu\n", sizeof(Base));
printf("Size of object b: %lu\n", sizeof(b));
printf("Size of class Derived: %lu\n", sizeof(Derived));
printf("Size of object d: %lu\n", sizeof(d));
return 0;
}

Output:

输出:

Size of class Base: 8
Size of object b: 8
Size of class Derived: 12
Size of object d: 12

Just changing the order of member we found that derived class is having size 12 Bytes now. So there must be some better alignment now.

只需更改成员的顺序,我们发现派生类的大小现在为12个字节。 因此,现在必须进行更好的调整。

So, as we can think of compiler went for greedy alignment and now it's able to align optimally (Remember compiler can’t change the order of data member).

因此,正如我们可以想到的那样,编译器进行了贪婪对齐,现在它可以进行最佳对齐(记住编译器无法更改数据成员的顺序)。

C++ | size of a class (4)

Above is the alignment for the Derived class and now the size is 12 Bytes, instead of 16 because of the above alignment. We saw that compiler keeps aligning greedily & that's why it aligned char b of base class member & char d, which is its member, in the same row. When it tried to align int c, it could not as only 2 bytes were left. But instead of int, if it was char only then it would have aligned in the same line.

上面是Derived类的对齐方式,由于上面的对齐方式,现在的大小为12个字节,而不是16个字节。 我们看到编译器保持贪婪地对齐,这就是为什么它在同一行中对齐基类成员的char b和其成员char d 。 当它尝试对齐int c时 ,它不能,因为只剩下2个字节。 但不是INT,如果它是焦炭才把它会在同一线上。

虚拟关键字及其对大小的影响 (The virtual keyword and its effect on size)

We know in the derived class it can inherit the base class as virtual too. What would be the size of the derived class in that case? Will there be any changes?

我们知道,在派生类中,它也可以继承虚拟类的基类。 在这种情况下,派生类的大小是多少? 会有变化吗?

The answer is yes. There will be an additional 8 bytes which is nothing but the size of VTPR (Virtual Table pointer)

答案是肯定的。 将有一个额外的8个字节,不过就是VTPR(虚拟表指针)的大小

So, for the first derived class example, we got 16 Bytes, but here we have added the virtual keyword and got size 24 Bytes which is due to the size of VTPR.

因此,对于第一个派生类示例,我们获得了16个字节,但是由于VTPR的大小,我们在这里添加了virtual关键字并获得了24个字节的大小。

#include <bits/stdc++.h>
using namespace std;
class Base {
protected:
static int i;
int a;
char b;
public:
Base()
{
a = 0;
b = '#';
}
Base(int aa, char bb)
{
a = aa;
b = bb;
}
int get_int()
{
cout << a << endl;
return a;
}
char get_char()
{
cout << b << endl;
return b;
}
};
class Derived : virtual public Base {
private:
char d;
int c;
public:
Derived()
{
c = 0;
d = '#';
}
Derived(int cc, char dd)
{
c = cc;
d = dd;
}
int get_int()
{
cout << c << endl;
return c;
}
char get_char()
{
cout << d << endl;
return d;
}
};
int main()
{
Base b;
Derived d;
printf("Size of class Base: %lu\n", sizeof(Base));
printf("Size of object b: %lu\n", sizeof(b));
printf("Size of class Derived: %lu\n", sizeof(Derived));
printf("Size of object d: %lu\n", sizeof(d));
return 0;
}

Output:

输出:

Size of class Base: 8
Size of object b: 8
Size of class Derived: 24
Size of object d: 24

So, here we got the idea of a normal class and object size. We learnt how the compiler aligns the data members and add padding. Also, we extended the discussion to the size of the derived class.

因此,这里我们有了一个普通的类和对象大小的想法。 我们了解了编译器如何对齐数据成员并添加填充。 同样,我们将讨论扩展到派生类的大小。

To end the discussion let me just throw a brain teaser. What do you think would be the size of an empty class?

为了结束讨论,我只想动脑子。 您认为空班级的人数多少?

Do you think it's 0?

你认为是0吗?

#include <bits/stdc++.h>
using namespace std;
class A {
};
int main()
{
printf("Size of class A: %lu\n", sizeof(A));
return 0;
}

Output:

输出:

Size of class A: 1

Well, the size of the empty class is not 0. This is actually to ensure that two different objects will have different addresses.

嗯,空类的大小不为0。这实际上是为了确保两个不同的对象具有不同的地址。

翻译自: https://www.includehelp.com/cpp-tutorial/size-of-a-class-in-cpp-padding-alignment-in-class-size-of-derived-class.aspx

c语言格式对齐填充

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540426.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ELK系列~对fluentd参数的理解

这段时候一直在研究ELK框架&#xff0c;主要集成在对fluentd和nxlog的研究上&#xff0c;国内文章不多&#xff0c;主要看了一下官方的API&#xff0c;配合自己的理解&#xff0c;总结了一下&#xff0c;希望可以帮到刚入行的朋友们&#xff01; Fluentd&#xff08;日志收集与…

css 文本背景色透明_如何使用CSS将文本或图像的背景设置为透明?

css 文本背景色透明Introduction: 介绍&#xff1a; In web development, there are numerous ways by which we can style our websites or web pages. You can make use of lots of properties for creating attractive and responsive websites. 在Web开发中&#xff0c;我…

一次前端笔试总结

1.有一个长度未知的数组a&#xff0c;如果它的长度为0就把数字1添加到数组里面&#xff0c;否则按照先进先出的队列规则让第一个元素出队。 分析&#xff1a;这道题主要是考核了数组的队列方法和栈方法。另外&#xff0c;原题还有字数限制的&#xff0c;只有在字数小于30并且结…

SSL

今天遇到一位网友要求老蒋将他当前已经在使用的WDCP面板环境&#xff0c;给某个站点添加SSL证书&#xff0c;实现HTTPS网址访问。在过去的几篇文章中&#xff0c;老蒋也有分享过不少在Linux VPS中对应的WEB环境安装SSL证书的经历&#xff0c;其实总体来看都大同小异&#xff0c…

应用宝认领应用

2019独角兽企业重金招聘Python工程师标准>>> 【Android】命令行jarsigner签字和解决找不到证书链错误 1、签名失败 $jarsigner -verbose -keystore /Volumes/Study/resourcesLib/Qunero-achivements/AndroidApp/QuLordy-signed-key -signedjar ./signed_XiaomiVerif…

Squid服务日志分析

Squid服务日志分析 Apache 和 Squid 是两种著名的代理缓存软件&#xff0c;但Squid 较 Apache 而言是专门的代理缓存服务器软件&#xff0c;其代理缓存的功能强大&#xff0c;支持 HTTP/1.1 协议&#xff0c;其缓存对象也较多&#xff1b;并且 Squid 的缓存管理模块和访问控制模…

云时代 揭开性能监测战略的隐秘优势

云时代的性能监测战略 能够对各种变化做出快速响应而不偏离重心和企业发展动力&#xff0c;正逐渐成为各行各业、各种规模企业的奋斗目标。业务敏捷性通常是运营良好&#xff0c;可实现盈利的企业标志。实现这一目标意味着公司已经成功地利用业务关键型技术来提高生产率&#x…

聊聊全站HTTPS带来的技术挑战

日前写的文章里了讨论了数据传输的安全性的问题&#xff0c;最后一部分提到了通过HTTPS解决数据传输安全性的方案。那么一个新问题又来了&#xff0c;实施全站HTTPS的过程中&#xff0c;我们可能会遇到哪些技术问题?所以我今天和大家一起来算一下这个账&#xff0c;将技术成本…

4.3/4.4 磁盘分区

2019独角兽企业重金招聘Python工程师标准>>> 添加虚拟磁盘 第一步&#xff0c;选择虚拟机中的“设置” 第二步&#xff0c;选择“添加硬盘” 第三步&#xff0c;选择_SCSI &#xff08;推荐&#xff09; # 保持默认 第四步&#xff0c;选择“创建新的虚拟磁盘…

RoboMaster 2017:机器人版的「王者农药」,工程师们的竞技时代

8月6日晚&#xff0c;第十六届全国大学生机器人大赛 RoboMaster 2017机甲大师赛在华润深圳湾体育中心“春茧”体育馆举行&#xff0c;关于这个比赛的盛况已经无需赘述&#xff0c;去年雷锋网参加上届比赛时&#xff0c;报道的是「像看了一场演唱会」&#xff0c;如果用演唱会来…

【初学者必读】:前端工程师的知识体系

下图是前端工程师图解&#xff1a; 前端开发的核心是HTML CSS JavaScript。本质上它们构成一个MVC框架&#xff0c;即HTML作为信息模型&#xff08;Model&#xff09;&#xff0c;CSS控制样式&#xff08;View&#xff09;&#xff0c;JavaScript负责调度数据和实现某种展现逻…

使用Prometheus监控Cloudflare的全球网络

Matt Bostock在SRECON 2017欧洲大会的演讲中&#xff0c;介绍了如何使用Prometheus实现对CloudFlare分布于全球的架构和网络的监控。Prometheus是一种基于度量进行监控的工具&#xff0c;CloudFlare是一家CDN、DNS和DDoS防御&#xff08;Mitigation&#xff09;服务提供商。\\基…

开始吧

2019独角兽企业重金招聘Python工程师标准>>> 写C三年有余&#xff0c;在技术方面也算小有所成。准备在这里分享一些C进阶、Python、Golang技术文章。 CSDN博客地址&#xff1a; http://blog.csdn.net/godmaycry 以后博客同步更新。 转载于:https://my.oschina.net/u…

Exchange server 2013(十四)WSUS部署及组策略设置(2)

我们继续上一节未完的博客&#xff0c;继续我们的WSUS设置。[上一章节标题&#xff1a;Exchange server 2013(十四)WSUS部署及组策略设置(1) 网址&#xff1a;http://1183839.blog.51cto.com/blog/1173839/1182366] 首先单击自动审批,来修改审批规则,也就是说当wsus侦测到新的更…

用MATLAB结合四种方法搜寻罗马尼亚度假问题

选修了cs的AI课&#xff0c;开始有点不适应&#xff0c;只能用matlab硬着头皮上了&#xff0c;不过matlab代码全网仅此一份&#xff0c;倒有点小自豪。 一、练习题目 分别用宽度优先、深度优先、贪婪算法和 A*算法求解“罗马利亚度假问题”。具体地图我这里不给出了&#xff0c…

[转]Paul Adams:为社交设计

为社交设计 Strong, Weak, and Temporary Ties by Paul Adams on 2010/04/09 PS&#xff1a;作者Paul Adams Facebook全球品牌体验总监 电话和手机聚集十亿用户用了15年的时间&#xff0c;而Facebook只用了9个月。我们看到越来越多的人开始用在线社交网络&#xff0c;这种网络好…

Android Framework中的Application Framework层介绍

Android的四层架构相比大家都很清楚&#xff0c;老生常谈的说一下分别为&#xff1a; Linux2.6内核层&#xff0c;核心库层&#xff0c;应用框架层&#xff0c;应用层。我今天重点介绍一下应用框架层Framework。 Framework层为我们开发应用程序提供了非常多的API&#xff0c;我…

ORACLE中创建如何创建表,并设置结构和默认值

使用select语句查看EMP表&#xff0c;根据COMM排序 默认情况下&#xff0c;空值会自动排列在尾部。 利用nulls last排序时将空值置底 利用nulls first排序时将空值置顶 例 创建一张出版社表 使用语句 create table 表名&#xff08;列名1 类型&#xff0c;列名2 类型&#xff0…

暴风TV请来中国人工智能first lady冯雁教授任首席科学家

今日下午&#xff0c;暴风AI无屏电视发布会现场&#xff0c;暴风TV宣布邀请号称“中国人工智能first lady”、于香港科技大学任教的冯雁教授&#xff0c;担任暴风TV人工智能首席科学顾问。 冯雁教授于现场表示&#xff0c;选择暴风TV合作的重要原因&#xff0c;一方面在于其个人…

gulp之gulp.watch报错

gulpfile.js如下&#xff1a; 问题&#xff1a; 第一次改动文件&#xff0c;监听正常。再次改动&#xff0c;报错&#xff0c;如下&#xff1a; 解决&#xff1a; 总结&#xff1a; 意思&#xff0c;gulpsequence这玩意儿返回的thunk只能执行一次 转载于:https://www.cnblogs.c…