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;日志收集与…

[转载] Java中的50个关键字

参考链接&#xff1a; Java平台如何独立 Java中的50个关键字 关键字也称为保留字&#xff0c;是指java语言中规定了特定含义的标示符。对于保留字&#xff0c;用户只能按照系统规定的方式使用&#xff0c;不能自行定义。Java中有50个常用关键字&#xff1a; 与数据类型相关…

MySQL 直接存储图片并在 html 页面中展示,点击下载

数据库实体类&#xff1a; package com.easy.kotlin.picturecrawler.entityimport java.util.* import javax.persistence.*Entity Table(indexes arrayOf(Index(name "idx_url", unique true, columnList "url"),Index(name "idx_category"…

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.1Java使用JDBC原生方式连接MySql数据库

参考链接&#xff1a; Java数据库连接JDBC驱动程序 前言&#xff1a;今天有朋友问我原生的java连接数据库&#xff0c;因为框架的使用&#xff0c;如果基础不牢固的人&#xff0c;是很容易遗忘原生的连接方式。今天正好趁此做一下回顾&#xff1a; 这里只考虑原生方式&#x…

maven安装及集成myeclipse

第一步&#xff1a;下载和安装 1、官网下载Maven&#xff1a;http://maven.apache.org/download.cgi 2、解压到一个文件夹2、设置环境变量&#xff1a;如&#xff1a;M2_HOME&#xff1a;D:\JAVA\apache-maven-3.0.5在path中添加;%M2_HOME%\bin;第二步&#xff1a;和MyEclipse集…

[转载] Java泛型详解:<T>和Class<T>的使用。泛型类,泛型方法的详细使用实例

参考链接&#xff1a; Java中的main()函数是强制性的吗 一、引入 1、泛型是什么 首先告诉大家ArrayList就是泛型。那ArrayList能完成哪些想不到的功能呢&#xff1f;先看看下面这段代码&#xff1a; [java] view plain copy ArrayList<String> strList new ArrayL…

数字和数字根的总和_使用8086微处理器查找8位数字的数字总和

数字和数字根的总和Problem statement: 问题陈述&#xff1a; Write an assembly language program in 8086 microprocessor to find sum of digit of an 8 bits number using 8 bits operation. 在8086微处理器中编写汇编语言程序&#xff0c;以使用8位运算找到8位数字的位数…

[转载] Java笔试题集锦

参考链接&#xff1a; 关于Java中文件名和类名的误解 Java笔试题集锦 1.MVC的各个部分都有那些技术来实现?如何实现? 答&#xff1a;MVC是Model&#xff0d;View&#xff0d;Controller的简写。"Model" 代表的是应用的业务逻辑&#xff08;通过JavaBean&#xff…

gcc -pthread_错误-在GCC Linux中使用C程序未定义对'pthread_create'的引用

gcc -pthread在Linux中修复对pthread_create的未定义引用 (Fixing undefined reference to pthread_create in Linux) This is a common error while compiling C program in GCC/G Linux. This error occurs when you are using pthread_create function to create threads in…

[转载] Java面试题全集(上)

参考链接&#xff1a; 如何运行不同目录中的Java类文件 2013年年底的时候&#xff0c;我看到了网上流传的一个叫做《Java面试题大全》的东西&#xff0c;认真的阅读了以后发现里面的很多题目是重复且没有价值的题目&#xff0c;还有不少的参考答案也是错误的&#xff0c;于是我…

python重载运算符乘法_Python | 使用乘法运算符创建一个字符串的多个副本

python重载运算符乘法Given a string and we have to create its multiple copies by using multiplication operator in Python? 给定一个字符串&#xff0c;我们必须通过在Python中使用乘法运算符来创建其多个副本&#xff1f; If you want to create multiple copies of …

一次前端笔试总结

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

Java文件类boolean setLastModified(long set_new_time)方法,包含示例

文件类boolean setLastModified(long set_new_time) (File Class boolean setLastModified(long set_new_time)) This method is available in package java.io.File.setLastModified(long set_new_time). 软件包java.io.File.setLastModified(long set_new_time)中提供了此方法…

[转载] Linux里面的文件目录类指令

参考链接&#xff1a; 如何运行不同目录中的Java类文件 引用&#xff1a;尚硅谷韩老师的《尚硅谷-Linux-经典升级》 日常总结 pwd 指令 &#xff08;显示当前工作目录的绝对路径&#xff09; 基本语法 pwd (功能描述&#xff1a;显示当前工作目录的绝对路径) …

[转载] 微服务安全和治理

参考链接&#xff1a; 微服务介绍 在整体式架构中&#xff0c;由于运行应用程序的运行时环境相对隔离&#xff0c;所以治理和安全保护很简单。微服务架构具有典型的革新特征&#xff0c;给活动的治理和应用程序的安全威胁保护带来了更多挑战。 微服务架构中的安全性 微服务…

SSL

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

[转载] Java中如何引用另一个类里的集合_Java工程师面试题整理

参考链接&#xff1a; 在Java中将预定义的类名用作类或变量名 花了一星期把学过的都整理一遍 尽量易懂&#xff0c;从基础到框架 最新版大厂面经汇总出炉&#xff0c;持续更新中 汇总完了上传网盘&#xff0c;设计到后端架构师的一切知识 如果没更新就代表我死了 一&#xff0…

应用宝认领应用

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

[转载] Java | Java 面向对象知识小抄

参考链接&#xff1a; 在Java中将预定义的类名用作类或变量名 0. 前言 下面是本篇的内容提纲&#xff1a; 1. 类 Java 中类的声明形式如下所示&#xff0c;变量的声明和方法的定义意味着只能声明变量、初始化、方法定义等&#xff0c;而不能在方法外进行赋值等操作。 …