2010-05-13 10 views
9

दो उद्धरण ++ मानक, §1.8:खाली आधार वर्ग अनुकूलन सी से

एक वस्तु भंडारण का एक क्षेत्र है।

बेस क्लास सबोबजेक्ट्स का आकार शून्य हो सकता है।

मुझे नहीं लगता कि भंडारण का क्षेत्र शून्य आकार का हो सकता है। इसका मतलब यह होगा कि कुछ बेस क्लास सबोबजेक्ट्स वास्तव में वस्तुओं नहीं हैं। ये कथन कैसे मौजूद हैं?

+1

आपको लगता है कि भंडारण का क्षेत्र शून्य आकार का नहीं हो सकता है? जाहिर है यह कर सकते हैं :) –

+1

कॉल मॉलोक (0)। – bmargulies

+1

@bmargulies 'malloc' विशेष रूप से इतना है कि यह शून्य आकार की एक वस्तु बनाने के लिए की जरूरत नहीं है सी में शब्दों है:" का अनुरोध किया अंतरिक्ष के आकार शून्य है, व्यवहार कार्यान्वयन-de फाई नेड है: या तो एक नल पॉइंटर दिया जाता है , या व्यवहार ऐसा है जैसे आकार कुछ nonzero मान थे " –

उत्तर

10

"क्षेत्र" की परिभाषा पर एक दार्शनिक तर्क अनावश्यक है।

1,8/5 कहते हैं, "जब तक यह थोड़ा-क्षेत्र, एक सबसे व्युत्पन्न वस्तु एक गैर शून्य आकार ... बेस वर्ग उप वस्तुओं शून्य आकार हो सकता है नहीं होगा"।

तो मानक काफी स्पष्ट है क्या वस्तुओं (और इसलिए क्या "भंडारण के क्षेत्रों") का आकार शून्य हो सकता है। यदि आप मानक से असहमत हैं कि "क्षेत्र" का अर्थ अंग्रेजी में क्या है, तो यह एक बात है, आप लेखकों (गैर-प्रोग्रामिंग से संबंधित) साहित्यिक कौशल को गलती कर सकते हैं। उस मामले के लिए आप अपने काव्य कौशल (14.7.3/7) को गलती कर सकते हैं लेकिन कक्षा के प्रकारों के आकार के बारे में मानक यहां क्या कहता है यह स्पष्ट है।

मानकों को पढ़ने के लिए व्यावहारिक तरीका है कि एक शब्द के दो प्रशंसनीय व्याख्याओं को देखते हुए, एक जो सीधे मानक का एक ही अनुभाग में एक और वाक्य का खंडन नहीं करता चयन किया गया है। उस शब्द का चयन न करें जो शब्द के आपके व्यक्तिगत पसंदीदा उपयोग, या यहां तक ​​कि सबसे आम उपयोग से अधिक बारीकी से मेल खाता है।

+0

"जब तक यह एक बिट-फ़ील्ड न हो, तब तक सबसे अधिक व्युत्पन्न ऑब्जेक्ट में शून्य-शून्य आकार होगा" जो 'नए int [0]' के साथ संघर्ष करता है, जिसे "कोई तत्व नहीं वाले एरे आवंटित" कहा जाता है। क्या इसका मतलब यह है कि वास्तव में * एरे * उस मामले में आंतरिक पैडिंग करते हैं? –

+0

मुझे नहीं लगता कि एक सरणी सबसे अधिक व्युत्पन्न वस्तु है। 1.8/4: "यदि एक पूर्ण वस्तु ... वर्ग प्रकार का है, तो इसका प्रकार सबसे व्युत्पन्न वर्ग माना जाता है ... सबसे व्युत्पन्न वर्ग प्रकार की वस्तु को सबसे व्युत्पन्न वस्तु कहा जाता है" –

+0

@Steve यह कहता है " सबसे व्युत्पन्न वर्ग प्रकार या गैर-वर्ग प्रकार के किसी ऑब्जेक्ट को सबसे व्युत्पन्न वस्तु कहा जाता है "। - संपादित करें: सी ++ 03 शब्द एफसीडी शब्द से अलग दिखता है। –

9

सी ++ शून्य आकार की एक वस्तु की अनुमति नहीं है, क्योंकि हर वस्तु एक अनूठा स्मृति पता होना चाहिए। तो यदि आपके पास है:

struct empty {}; 

// ... 

empty myempty; 
empty* ptr = &myempty; 

तो ptr एक अद्वितीय स्मृति पते पर इंगित करना चाहिए। मानक इस उद्देश्य के लिए किसी वस्तु के लिए न्यूनतम आकार 1 बाइट है। इसी प्रकार, आकार 0 के आवंटन की अनुमति है, और एक मान्य सूचक लौटने के लिए, भले ही उस सूचक के लिए लिख अनुमति नहीं है (इस malloc(0) के लिए काम करता है, और new empty एक बाइट के लिए सूचक देता है, sizeof(empty) == 1 के बाद से)।

अगर मैं ऐसा तरह empty से निकाले जाते हैं:

struct derived : public empty 
{ 
    int data; 
} 

वहाँ नहीं रह गया है, आधार वर्ग empty एक बाइट कब्जे में किसी भी बिंदु है, क्योंकि सभी deriveddata सदस्य की वजह से एक विशिष्ट पता होगा। उद्धरण "बेस क्लास सबोबजेक्ट्स का शून्य आकार हो सकता है" इस मामले में, संकलक के लिए empty, sizeof(derived) == 4 के लिए किसी भी स्थान का उपयोग न करने के लिए मौजूद है। शीर्षक के अनुसार, यह सिर्फ एक अनुकूलन है, और शून्य स्थान पर कब्जा करने के लिए derived के भाग के लिए यह पूरी तरह से कानूनी है।

+0

वास्तव में 'आकार (खाली)' को बड़ा होने की अनुमति है, और अधिकांश कंपाइलर इसे कम से कम मशीन शब्द चौड़ाई बनाने जा रहे हैं। –

+0

"प्रत्येक ऑब्जेक्ट में एक अद्वितीय स्मृति पता होना चाहिए" - मानक में गलत शब्द के बावजूद, प्रत्येक ऑब्जेक्ट _not_ को एक अद्वितीय स्मृति पता होना आवश्यक है। एक ऑब्जेक्ट उसी शुरुआत में उपरोक्त के रूप में एक ही पता कर सकता है, और/या बेस क्लास सबोबजेक्ट। यह कहना चाहिए कि प्रत्येक _complete_ ऑब्जेक्ट में एक अनूठा पता होना चाहिए। – davmac

2

सी ++ मानक 1.8.5 राज्यों: -

जब तक यह थोड़ा-क्षेत्र (9.6), एक सबसे व्युत्पन्न वस्तु एक गैर शून्य आकार होगा और एक या अधिक पर कब्जा करेगा भंडारण के बाइट्स। बेस क्लास सबोबजेक्ट्स में शून्य आकार हो सकता है। एक तुच्छ रूप से कॉपी करने योग्य या मानक-लेआउट प्रकार (3।9) भंडारण के संगत बाइट्स पर कब्जा करेगा।

तो, मानक एक बेस-क्लास को कम करता है जिसमें कोई डेटा सदस्य नहीं है (और कोई आभासी नहीं) एक ही प्रकार को एक अन्य प्रकार के रूप में एक अन्य उपरोक्त के रूप में साझा करने के लिए। आप खाली आधार वर्ग आकार की तरह के साथ चारों ओर खेल सकते हैं ...

struct a{}; 
struct a1{}; 
struct b : public a, public a1{char c;}; 


int main() 
{ 
    std::cout << sizeof(b) << "\n"; 
    std::cout << sizeof(b::a); 
} 


Which outputs (ignoring padding)... 

1 
1 


now try: 


struct a{}; 
struct b : public a {a ax;}; 


int main() 
{ 
    std::cout << sizeof(b) << "\n"; 
    std::cout << sizeof(b::a); 
} 


and the output is ... 

2 
1 

क्योंकि एक के दो उदाहरणों (एक आधार के रूप और एक सदस्य के रूप में) अलग पतों होना आवश्यक है।

बीटीडब्ल्यू: "बी :: ए" "ए" कहने का एक और तरीका है। स्कोप एक्सेस ऑपरेटर की उपस्थिति "बी प्रकार के बी के बेस-क्लास सबोबजेक्ट" का अनुरोध नहीं करती है। श्लोक 5.3.3/2 कहता है: - बेस क्लास सबोबजेक्ट के आकार को लागू करते समय, परिणाम उस ऑब्जेक्ट के प्रकार का आकार होता है।

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