2010-03-18 10 views
7

कोई डेटा सदस्य वाले वर्ग का आकार 1 बाइट के रूप में वापस किया जाता है, भले ही एक निहित 'यह' सूचक घोषित किया गया हो। आकार वापस 4 बाइट्स (32 बिट मशीन पर) नहीं होना चाहिए? मैं लेखों में आया जो इंगित करता है कि 'इस' सूचक वस्तु के आकार की गणना के लिए गिना नहीं जाता है। लेकिन मैं इसके कारण को समझने में असमर्थ हूं। इसके अलावा, यदि कोई सदस्य फ़ंक्शन आभासी घोषित किया गया है, तो कक्षा का आकार अब 4 बाइट्स के रूप में वापस कर दिया गया है। इसका मतलब है कि ऑब्जेक्ट के आकार की गणना के लिए vptr गिना जाता है। ऑब्जेक्ट के आकार की गणना के लिए वीपीआरआर क्यों माना जाता है और 'यह' पॉइंटर अनदेखा क्यों किया जाता है?'इस' सूचक के साथ एक वर्ग का आकार

+0

डुप्लिकेट: http://stackoverflow.com/questions/621616/c-what-is-the-size-of-an-object-of-an-empty-class http://stackoverflow.com/questions/2362097/खाली-कक्षा-इन-सी –

उत्तर

6

this पॉइंटर कक्षा का सदस्य नहीं है। यह सिर्फ एक ऐसा निर्माण है जिसका उपयोग वर्तमान उदाहरण के संदर्भ में कक्षा से संबंधित विधियों में किया जाता है।

अगर आप इस तरह एक वर्ग है:

class IntPair 
{ 
public: 
    IntPair(int a, int b) : _a(a), _b(b) { } 

    int sum() const { return _a + _b; } 

public: 
    int _a; 
    int _b; 
}; 

इस वर्ग के केवल प्रत्येक उदाहरण के लिए int के दो उदाहरणों के लिए जगह की जरूरत है। एक बार जब आप एक उदाहरण बना लेते हैं और sum() विधि चला रहे हैं, तो उस विधि को उदाहरण के लिए पॉइंटर कहा जाता है, लेकिन वह सूचक हमेशा कहीं से आता है, यह ऑब्जेक्ट इंस्टेंस में संग्रहीत नहीं होता है।

उदाहरण के लिए:

IntPair *fib12 = new IntPair(89, 144); 

cout << fib12->sum(); 

सूचना कैसे चर कि this सूचक बन जाता है बाहर संग्रहीत किया जाता है वस्तु, गुंजाइश है कि यह बनाया में।

static int sum2(const IntPair* instance) 
{ 
    return instance->_a + instance->_b; 
} 

ऊपर वर्ग के भीतर परिभाषित किया गया है (इसलिए यह निजी सदस्यों तक पहुँच सकते हैं), वहाँ कोई अंतर नहीं है:

आप, वास्तव में, हमेशा एक विधि से एक की तरह ऊपर में बदलना कर सकते हैं। वास्तव में, यह दृश्य के पीछे विधियों को कैसे लागू किया जाता है; this पॉइंटर सभी सदस्य विधियों के लिए सिर्फ एक छिपी हुई तर्क है।

कॉल बन जाएगा:

IntPair* fib12 = new IntPair(89, 144); 

cout << IntPair::sum2(fib12); 
4

'इस' वर्ग में एक डेटा सदस्य के रूप में संग्रहीत नहीं है, यह सिर्फ एक वर्ग के उदाहरण के लिए 'सूचक'। इस विधि को पारित 'छुपा तर्क' के रूप में विचार करें। असल में, Win32 सिस्टम पर इसे अक्सर एक्स्क्स रजिस्टर में पारित किया जाता है (जैसा कि मैंने शुरू में सोचा था वैक्स नहीं)।

जैसे ही आपके पास 1 या अधिक वर्चुअल विधियां हों, आपके एप्लिकेशन को पॉइंटर्स को वर्चुअल विधियों को स्टोर करने का एक तरीका चाहिए। इसे vtable कहा जाता है, जो एक ही कक्षा के सभी उदाहरणों के समान है। चूंकि आपको रन-टाइम पर जानने की आवश्यकता है, जिसे 'वर्चुअल विधि' कॉल करने के लिए कॉल करने के लिए 'स्पष्ट' विधि क्लास इंस्टेंस में एक पॉइंटर को संग्रहीत किया जाता है। इसलिए vtable-pointer (या vptr) को 4 बाइट्स (या 64-बिट सिस्टम पर 8 बाइट्स) की आवश्यकता होती है।

+1

मैंने सोचा कि यह 'ecx' में पारित किया गया था। – Blindy

+0

ओह, हाँ आप सही हैं। ईएक्स का उपयोग वापसी मूल्य के लिए किया जाता है। (मैंने पोस्ट संपादित किया) – Patrick

2

यह पॉइंटर ऑब्जेक्ट के अंदर संग्रहीत नहीं है। ऐसा करने की कोई ज़रूरत नहीं है। फ़ंक्शंस का आह्वान करने के लिए आपके पास पहले से एक पॉइंटर या ऑब्जेक्ट है। 1 के आकार के लिए, सी ++ मानक रिकॉर्ड्स जो वस्तुओं को विकृत करते हैं, अलग-अलग पते होते हैं।

-1

सूचक का आकार हमेशा स्मृति में संग्रहीत करने के लिए आवश्यक पॉइंटर के प्रकार का आकार होता है।

उदाहरण के लिए, एक int की स्मृति पते के एक 64-बिट वास्तुकला पर 32-बिट, तो है अगर

पूर्णांक एक = 10; int * बी = और ए; आकार (बी); // 32 आकार (& बी); 64

+0

इसके अलावा आकार() बिट्स की संख्या देता है, बिट्स, आकार (int *) और sizeof (int **) अलग नहीं हो सकता है। – PlasmaHH

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