C++
वस्तु प्रकारों का लेआउट
खोज…
टिप्पणियों
अभिन्न प्रकारों का आकार भी देखें।
वर्ग प्रकार
"क्लास" से हमारा तात्पर्य एक प्रकार से होता है जिसे class
या struct
कीवर्ड (लेकिन enum struct
या enum class
) का उपयोग करके परिभाषित किया गया था।
यहां तक कि एक खाली वर्ग अभी भी भंडारण के कम से कम एक बाइट पर कब्जा कर लेता है; इसलिए यह पूरी तरह से पैडिंग से मिलकर बनेगा। यह सुनिश्चित करता है कि यदि
p
किसी खाली वर्ग के ऑब्जेक्ट को इंगित करता है, तोp + 1
एक अलग पता है और एक अलग ऑब्जेक्ट को इंगित करता है। हालांकि, एक खाली वर्ग के लिए आधार वर्ग के रूप में उपयोग किए जाने पर इसका आकार 0 होना संभव है। खाली आधार अनुकूलन देखें।class Empty_1 {}; // sizeof(Empty_1) == 1 class Empty_2 {}; // sizeof(Empty_2) == 1 class Derived : Empty_1 {}; // sizeof(Derived) == 1 class DoubleDerived : Empty_1, Empty_2 {}; // sizeof(DoubleDerived) == 1 class Holder { Empty_1 e; }; // sizeof(Holder) == 1 class DoubleHolder { Empty_1 e1; Empty_2 e2; }; // sizeof(DoubleHolder) == 2 class DerivedHolder : Empty_1 { Empty_1 e; }; // sizeof(DerivedHolder) == 2
एक वर्ग प्रकार के ऑब्जेक्ट प्रतिनिधित्व में बेस क्लास और गैर-स्थिर सदस्य प्रकारों के ऑब्जेक्ट प्रतिनिधित्व होते हैं। इसलिए, उदाहरण के लिए, निम्न वर्ग में:
struct S { int x; char* y; };
किसी
S
ऑब्जेक्ट के भीतरsizeof(int)
बाइट्स का एक निरंतर अनुक्रम होता है, जिसे सबोबिज कहा जाता है , जिसमेंx
का मान होता है, औरsizeof(char*)
बाइट्स के साथ एक और सबबॉजेक्ट जिसमेंy
का मान होता है। दोनों को आपस में जोड़ा नहीं जा सकता।यदि एक वर्ग प्रकार में
t1, t2,...tN
साथ सदस्य और / या आधार वर्ग हैं, तो आकार कम से कम आकार का होना चाहिएsizeof(t1) + sizeof(t2) + ... + sizeof(tN)
पूर्ववर्ती अंक दिए गए । हालांकि, सदस्यों और आधार वर्गों की संरेखण आवश्यकताओं के आधार पर, कंपाइलर को सबजेक्ट के बीच या पूर्ण वस्तु की शुरुआत या अंत में पैडिंग डालने के लिए मजबूर किया जा सकता है।struct AnInt { int i; }; // sizeof(AnInt) == sizeof(int) // Assuming a typical 32- or 64-bit system, sizeof(AnInt) == 4 (4). struct TwoInts { int i, j; }; // sizeof(TwoInts) >= 2 * sizeof(int) // Assuming a typical 32- or 64-bit system, sizeof(TwoInts) == 8 (4 + 4). struct IntAndChar { int i; char c; }; // sizeof(IntAndChar) >= sizeof(int) + sizeof(char) // Assuming a typical 32- or 64-bit system, sizeof(IntAndChar) == 8 (4 + 1 + padding). struct AnIntDerived : AnInt { long long l; }; // sizeof(AnIntDerived) >= sizeof(AnInt) + sizeof(long long) // Assuming a typical 32- or 64-bit system, sizeof(AnIntDerived) == 16 (4 + padding + 8).
यदि संरेखण आवश्यकताओं के कारण किसी वस्तु में गद्दी डाली जाती है, तो आकार सदस्यों और आधार वर्गों के आकार के योग से अधिक होगा।
n
-by संरेखण के साथ, आकार आम तौर परn
का सबसे छोटा बहु होगा जो सभी सदस्यों और आधार वर्गों के आकार से बड़ा होता है। प्रत्येक सदस्यmemN
आम तौर पर एक पते जो की एक बहु है पर रखा जाएगाalignof(memN)
, औरn
आम तौर पर सबसे बड़ा हो जाएगाalignof
सभी सदस्यों के से बाहरalignof
रों। इसके कारण, यदि एक छोटेalignof
साथ एक सदस्य एक बड़ेalignof
सदस्य के साथ है, तो एक संभावना है कि बाद के सदस्य को पूर्व के तुरंत बाद रखे जाने पर ठीक से संरेखित नहीं किया जाएगा। इस मामले में, पैडिंग (एक संरेखण सदस्य के रूप में भी जाना जाता है) को दो सदस्यों के बीच रखा जाएगा, जैसे कि बाद के सदस्य का वांछित संरेखण हो सकता है। इसके विपरीत, यदि एक बड़ाalignof
सदस्य के साथ एक सदस्य एक छोटेalignof
सदस्य के साथ है, तो आमतौर पर कोई गद्दी आवश्यक नहीं होगी। इस प्रक्रिया को "पैकिंग" के रूप में भी जाना जाता है।
कक्षाएं आम तौर पर साझा करने के कारणalignof
सबसे बड़ा के साथ अपने सदस्य कीalignof
, वर्ग आम तौर पर करने के लिए गठबंधन किया जाएगाalignof
सबसे बड़ा निर्मित प्रकार वे प्रत्यक्ष या परोक्ष रूप में होते हैं की।// Assume sizeof(short) == 2, sizeof(int) == 4, and sizeof(long long) == 8. // Assume 4-byte alignment is specified to the compiler. struct Char { char c; }; // sizeof(Char) == 1 (sizeof(char)) struct Int { int i; }; // sizeof(Int) == 4 (sizeof(int)) struct CharInt { char c; int i; }; // sizeof(CharInt) == 8 (1 (char) + 3 (padding) + 4 (int)) struct ShortIntCharInt { short s; int i; char c; int j; }; // sizeof(ShortIntCharInt) == 16 (2 (short) + 2 (padding) + 4 (int) + 1 (char) + // 3 (padding) + 4 (int)) struct ShortIntCharCharInt { short s; int i; char c; char d; int j; }; // sizeof(ShortIntCharCharInt) == 16 (2 (short) + 2 (padding) + 4 (int) + 1 (char) + // 1 (char) + 2 (padding) + 4 (int)) struct ShortCharShortInt { short s; char c; short t; int i; }; // sizeof(ShortCharShortInt) == 12 (2 (short) + 1 (char) + 1 (padding) + 2 (short) + // 2 (padding) + 4 (int)) struct IntLLInt { int i; long long l; int j; }; // sizeof(IntLLInt) == 16 (4 (int) + 8 (long long) + 4 (int)) // If packing isn't explicitly specified, most compilers will pack this as // 8-byte alignment, such that: // sizeof(IntLLInt) == 24 (4 (int) + 4 (padding) + 8 (long long) + // 4 (int) + 4 (padding)) // Assume sizeof(bool) == 1, sizeof(ShortIntCharInt) == 16, and sizeof(IntLLInt) == 24. // Assume default alignment: alignof(ShortIntCharInt) == 4, alignof(IntLLInt) == 8. struct ShortChar3ArrShortInt { short s; char c3[3]; short t; int i; }; // ShortChar3ArrShortInt has 4-byte alignment: alignof(int) >= alignof(char) && // alignof(int) >= alignof(short) // sizeof(ShortChar3ArrShortInt) == 12 (2 (short) + 3 (char[3]) + 1 (padding) + // 2 (short) + 4 (int)) // Note that t is placed at alignment of 2, not 4. alignof(short) == 2. struct Large_1 { ShortIntCharInt sici; bool b; ShortIntCharInt tjdj; }; // Large_1 has 4-byte alignment. // alignof(ShortIntCharInt) == alignof(int) == 4 // alignof(b) == 1 // Therefore, alignof(Large_1) == 4. // sizeof(Large_1) == 36 (16 (ShortIntCharInt) + 1 (bool) + 3 (padding) + // 16 (ShortIntCharInt)) struct Large_2 { IntLLInt illi; float f; IntLLInt jmmj; }; // Large_2 has 8-byte alignment. // alignof(IntLLInt) == alignof(long long) == 8 // alignof(float) == 4 // Therefore, alignof(Large_2) == 8. // sizeof(Large_2) == 56 (24 (IntLLInt) + 4 (float) + 4 (padding) + 24 (IntLLInt))
यदि संरेखण के साथ सख्त संरेखण को मजबूर किया
alignas
, तो पैडिंग का उपयोग निर्दिष्ट संरेखण को पूरा करने के लिए टाइप करने के लिए किया जाएगा, तब भी जब यह अन्यथा छोटा होगा। उदाहरण के लिए, नीचे दी गई परिभाषा के साथ,Chars<5>
में अंत में डाले गए तीन (या संभवतः अधिक) पैडिंग बाइट्स होंगे ताकि इसका कुल आकार 8. हो। आकार के लिए 4 के संरेखण के साथ वर्ग के लिए यह संभव नहीं है 5 का क्योंकि उस वर्ग की एक सारणी बनाना असंभव होगा, इसलिए पैड बाइट्स डालकर आकार को 4 के गुणक में "गोल" करना चाहिए।// This type shall always be aligned to a multiple of 4. Padding shall be inserted as // needed. // Chars<1>..Chars<4> are 4 bytes, Chars<5>..Chars<8> are 8 bytes, etc. template<size_t SZ> struct alignas(4) Chars { char arr[SZ]; }; static_assert(sizeof(Chars<1>) == sizeof(Chars<4>), "Alignment is strict.\n");
- यदि किसी वर्ग के दो गैर-स्थैतिक सदस्यों के पास एक ही एक्सेस स्पेसियर है , तो बाद में घोषणा क्रम में आने वाले को ऑब्जेक्ट प्रतिनिधित्व में बाद में आने की गारंटी है। लेकिन अगर दो गैर-स्थैतिक सदस्यों के पास अलग-अलग पहुंच विनिर्देशक हैं, तो वस्तु के भीतर उनका सापेक्ष क्रम अनिर्दिष्ट है।
- यह अनिर्दिष्ट है कि किसी वस्तु के भीतर बेस क्लास सबोबिज किस क्रम में दिखाई देते हैं, क्या वे लगातार होते हैं, और क्या वे पहले, बाद में या सदस्य सबोबिज के बीच दिखाई देते हैं।
अंकगणित प्रकार
संकीर्ण चरित्र प्रकार
unsigned char
प्रकार एक द्विआधारी संख्या का प्रतिनिधित्व करने के लिए सभी बिट्स का उपयोग करता है। इसलिए, उदाहरण के लिए, यदि unsigned char
8 बिट लंबा है, तो एक char
ऑब्जेक्ट का 256 संभावित बिट पैटर्न 256 विभिन्न मूल्यों {0, 1, ..., 255} का प्रतिनिधित्व करता है। नंबर 42 को बिट पैटर्न 00101010
द्वारा दर्शाए जाने की गारंटी है।
signed char
प्रकार में कोई पैडिंग बिट्स नहीं है, अर्थात, यदि signed char
8 बिट लंबा है, तो इसमें 8 बिट्स की संख्या का प्रतिनिधित्व करने की क्षमता है।
ध्यान दें कि ये गारंटी संकीर्ण चरित्र प्रकारों के अलावा अन्य प्रकारों पर लागू नहीं होती है।
पूर्णांक प्रकार
अहस्ताक्षरित पूर्णांक प्रकार एक शुद्ध बाइनरी सिस्टम का उपयोग करते हैं, लेकिन इसमें पैडिंग बिट्स हो सकते हैं। उदाहरण के लिए, unsigned int
लिए 64 बिट लंबा होना संभव है (हालांकि संभावना नहीं है) केवल 0 और 2 32 - 1, समावेशी के बीच पूर्णांकों को संग्रहीत करने में सक्षम हो। अन्य 32 बिट्स पैडिंग बिट्स होंगे, जिन्हें सीधे नहीं लिखा जाना चाहिए।
हस्ताक्षर किए गए पूर्णांक प्रकार एक द्विआधारी प्रणाली का उपयोग करते हैं जिसमें साइन बिट और संभवतः पैडिंग बिट्स होते हैं। मान जो किसी हस्ताक्षरित पूर्णांक प्रकार की सामान्य श्रेणी से संबंधित हैं और संबंधित अहस्ताक्षरित पूर्णांक प्रकार में समान प्रतिनिधित्व है। उदाहरण के लिए, यदि एक unsigned short
वस्तु का बिट पैटर्न 0001010010101011
5291
मान का प्रतिनिधित्व करता है, तो यह short
वस्तु के रूप में व्याख्या किए जाने पर मूल्य 5291
भी प्रतिनिधित्व करता है।
यह कार्यान्वयन-परिभाषित है कि क्या एक दो के पूरक, एक के पूरक, या संकेत-परिमाण प्रतिनिधित्व का उपयोग किया जाता है, क्योंकि सभी तीन सिस्टम पिछले पैराग्राफ में आवश्यकता को पूरा करते हैं।
फ्लोटिंग पॉइंट प्रकार
फ्लोटिंग पॉइंट प्रकारों का मूल्य प्रतिनिधित्व कार्यान्वयन-परिभाषित है। आमतौर पर, float
और double
प्रकार IEEE 754 के अनुरूप होते हैं और 32 और 64 बिट लंबे होते हैं (इसलिए, उदाहरण के लिए, float
में 23 बिट्स सटीक होती हैं जो 8 एक्सपोनेंट बिट्स और 1 साइन बिट का पालन करें)। हालांकि, मानक कुछ भी गारंटी नहीं देता है। फ्लोटिंग पॉइंट प्रकारों में अक्सर "ट्रैप प्रतिनिधित्व" होता है, जो गणना में उपयोग किए जाने पर त्रुटियों का कारण बनता है।
Arrays
एक सरणी प्रकार में इसके तत्वों के बीच कोई पैडिंग नहीं है। इसलिए, तत्व प्रकार T
साथ एक सरणी क्रम में स्मृति में रखी गई T
ऑब्जेक्ट्स का एक क्रम है।
एक बहुआयामी सरणी सरणियों का एक सरणी है, और ऊपर पुनरावर्ती लागू होता है। उदाहरण के लिए, यदि हमारे पास घोषणा है
int a[5][3];
तो a
3 का 5 सरणियों की एक सरणी है int
रों। इसलिए, a[0]
, जिसमें तीन तत्व होते हैं a[0][0]
, a[0][1]
, a[0][2]
, a[1]
से पहले स्मृति में रखा जाता है, जिसमें सम्मिलित होता है a[1][0]
, a[1][1]
और a[1][2]
। इसे पंक्ति प्रमुख आदेश कहा जाता है।