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.pswp.cn/news/540426.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540426.shtml
英文地址,請注明出處:http://en.pswp.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;而不能在方法外進行賦值等操作。 …