2012-02-06 5 views
9

मैं सी ++ में नया हूं और सी ++ में एक अनूठी विशेषता मिली है। मैंने देखा कि खाली का आकार 1 बाइट है, मैंने कुछ शोध किया और पता चला कि ऐसा किया गया है क्योंकि प्रत्येक ऑब्जेक्ट का एक अलग पता होना चाहिए। लेकिन मैं जानना चाहता हूं कि उस 1 बाइट की सामग्री क्या है। मुझे पता है कि यह "यह" पॉइंटर नहीं रखता है, लेकिन क्या यह एक डमी बाइट है या वास्तव में कुछ सामग्री है ???सी ++ कक्षा खाली वर्ग का आकार 1 बाइट

उत्तर

11

कोई सामग्री नहीं है। यह सिर्फ एक डमी बाइट है।

हर class या struct, 0 की तुलना में अपने sizeof अधिक होना चाहिए अपने व्यवहार फलस्वरूप। यह मानक द्वारा अपेक्षित और अनिवार्य है।

+0

असल में जी ++ में 0 आकार वाले वर्ग को परिभाषित करना संभव है। मेरा जवाब देखें – TrueY

0

यह एक डमी बाइट-कन्स्ट्रक्टर और विनाशक छोटा होगा, कोई "डेटा संग्रहित नहीं है"।

2

बाइट की सामग्री देखने के लिए आप अपने डीबगर या printf("%x", *(unsigned char *)&myobj); जैसे कुछ सरल उपयोग कर सकते हैं। मैंने सी ++ विनिर्देश नहीं पढ़ा है, लेकिन मैं अनुमान अनुमान लगाता हूं कि बाइट की सामग्री अपरिभाषित है, इसलिए व्यवहार कंपाइलर और आपके ओएस पर निर्भर करता है।

3

बाइट में कुछ भी नहीं है, यह कुछ अन्य व्यवहार को बेहतर बनाने के लिए है। उदाहरण के लिए किसी अन्य में निहित खाली कक्षाओं के मामले पर विचार करें।

class Empty 
{ }; 

class TwoEmpties 
{ 
    Empty a; 
    Empty b; 
}; 

आप अलग होने की दो सदस्यों, &TwoEmpties::a और &TwoEmpties::b, के पते कर सकते हैं। इसके लिए उनके आकार का आकार होना चाहिए> 1. (या कंपाइलर को उनके बीच पैडिंग जोड़ना होगा, जो बदले में नियमों को जटिल करेगा जब संकलक कक्षाओं में पैडिंग जोड़ सकता है।)

+0

मान्य है कि आप ** ** ** अक्सर दो सदस्यों का पता चाहते हैं। दरअसल, अधिकांश मामलों में, आप ** सदस्यों के पते के बारे में ** देखभाल नहीं करते **। यह नियम अल्पसंख्यक उपयोग मामलों को पूरा करता है, हालांकि उन्हें न्याय के लिए पर्याप्त महत्वपूर्ण निर्णय लिया गया था। –

+0

@MaththieuM। माना। थोड़ा –

7

यह अनिवार्य है मानक द्वारा कि एक ही प्रकार की विभिन्न वस्तुओं के अलग-अलग पते होना चाहिए। यह बदले में सुनिश्चित करता है कि किसी भी ऑब्जेक्ट के लिए T, T* इस ऑब्जेक्ट (इस प्रकार के लिए) के एक स्पष्ट पहचानकर्ता के रूप में कार्य करता है।

अनुमोदित, आपको अक्सर यह जानने की आवश्यकता नहीं है कि दो वस्तुएं वास्तव में समान हैं या नहीं, लेकिन कभी-कभी (सी ++ निम्न-स्तरीय पहुंच दी जाती है) यह या तो आवश्यक या केवल सादा सुविधाजनक है।

इस प्रकार यह निर्दिष्ट किया गया है कि किसी ऑब्जेक्ट का शून्य आकार होना चाहिए।

इस नियम का एक अपवाद नहीं है, हालांकि:

: जब एक आधार वर्ग के रूप में एक खाली वर्ग का उपयोग कर, संकलक उदाहरण के लिए खाली बेस अनुकूलन ( EBO) लागू करने के लिए कुछ परिस्थितियों है, चुन सकते हैं
struct Empty {}; 

struct Slim: Empty { 
    int a; 
}; 

static_assert(sizeof(Slim) == sizeof(int), ""); 

सामान्य रूप से बेस क्लास का आकार जोड़ा जाता है, लेकिन इस विशेष मामले में यह आवश्यक नहीं है। हालांकि नियम यह है कि एक ही प्रकार के दो अलग-अलग वस्तुओं एक ही पते अभी भी कभी नहीं होना चाहिए लागू होते हैं, और इतने:

struct Fat: Empty { 
    Empty e; 
}; 

static_assert(sizeof(Fat) > sizeof(Empty), ""); 

EBO टेम्पलेट स्थितियों में private वंशानुक्रम का उपयोग के लिए मुख्य कारण है। उदाहरण के लिए:

template <typename Allocator> 
class MyClass: private Allocator { 
}; 

इस तरह, अगर यह पता चला है कि Allocator एक खाली वर्ग है, वहाँ नहीं किसी भी भूमि के ऊपर हो जाएगा।आम तौर पर, इस प्रकार अक्सर नीतियों के लिए उपयोग किया जाता है, उदाहरण के लिए भविष्यवाणी करता है कि आप map पर जाते हैं।

1

एक empty class has a sizeof 1 क्योंकि जब उस वर्ग की वस्तुएं बनाई जाती हैं तो उन्हें आकार = 0 में स्मृति में उसी स्थान पर संग्रहीत किया जाएगा।

मान लीजिए कि जब आप कोई ऑब्जेक्ट address is 1000 बनाते हैं।

यदि class is 0 का आकार object must be 0 का आकार भी है।

(therefore, object is located at 1000+0=1000) 

तो अब अगर किसी अन्य वस्तु से बना है,

Add. of 2nd object=1000+0th location 

दोनों वस्तुओं एक ही पता है और इस अपरिभाषित व्यवहार है और उत्पन्न नहीं करना चाहिए के रूप में वहाँ अस्पष्टता जो करने के लिए वस्तु के रूप में भेजा जा रहा है हो जाएगा ।

इसलिए empty classes are given a byte of memory ऐसी स्थितियों को होने से रोकने के लिए।

0

सभी उपरोक्त उत्तर मेरे ज्ञान के अनुसार सही नहीं है। सही जवाब डिफ़ॉल्ट रूप से 4 इनबिल्ट कार्यों है कि

  1. डिफ़ॉल्ट निर्माता

  2. डिफ़ॉल्ट नाशक

  3. कॉपी निर्माता

  4. अतिभारित कार्य जब वर्ग की वस्तु बन जाता है कहा जाता है है ऑपरेटर

इसलिए खाली वर्ग के आकार 1byte है, उदाहरण: इस

#include<iostream> 
using namespace std; 
class Test 
{ 
}; 
int main() 
{ 
Test t; 
cout<< "size of empty class is "<<sizeof(t); 
} 
0

मैं इसी तरह की समस्या का सामना करना पड़ा कोशिश करते हैं और ऐसा लगता है कि एक एक छोटे से चाल के साथ शून्य लंबाई के साथ एक वर्ग को परिभाषित कर सकते हैं। मैं अगर यह सिर्फ जी की वजह से ++ है पता नहीं है, लेकिन निम्नलिखित कोड स्निपेट देखें:

struct ONE {}; 
struct ZERO { char x[0]; }; 

int main() { 
    cout << sizeof(ONE) << ", " << sizeof(ZERO) << endl; 

    ONE* po1 = new ONE; 
    ONE* po2 = new ONE; 
    cout << po1 << ", " << po2 << endl; 

    ZERO* pz1 = new ZERO; 
    ZERO* pz2 = new ZERO; 
    cout << pz1 << ", " << pz2 << endl; 
} 

उत्पादन होता है:

1, 0 
0xe4f010, 0xe4f030 
0xe4f050, 0xe4f070 

तो एक खाली वर्ग के आकार से एक है (के अनुसार सी ++ मानक), लेकिन अगर इसमें शून्य लंबाई सरणी फ़ील्ड है तो आकार शून्य हो जाएगा। यदि new के साथ ढेर पर एक नया वास्तव में शून्य आकार का वर्ग आवंटित किया गया है तो एक वैध पता वापस कर दिया जाता है और यदि कई बार आवंटित किए जाते हैं तो उनके पॉइंटर्स विभिन्न मेमोरी पतों पर इंगित कर रहे हैं।

+0

शब्द को ठीक किया गया, ठीक है, एक स्थिर रूप से शून्य-लंबाई सरणी खराब है। – Deduplicator

+0

@Deduplicator शायद आप सही हैं, लेकिन मैंने कई बार इस तरह के structs (char [0] को अंतिम आइटम के रूप में देखा है) देखा है। तो यह किसी भी तरह फैल गया है। – TrueY

+0

संरचना { int लंबाई; चार डी [0]; }; परिवर्तनीय रिकॉर्ड लंबाई * चाल * है (हालांकि मैं कुछ भी इतनी शक्तिशाली 'चाल' कहने से नापसंद करता हूं :))। –

संबंधित मुद्दे