2012-06-07 15 views
5

जैसा कि मैं समझता हूं, किसी ऑब्जेक्ट में virtual फ़ंक्शन पॉइंटर तालिका का स्थान संकलक निर्भर है।
क्या इस पॉइंटर को अंत में या इसके विपरीत बनाम ऑब्जेक्ट की शुरुआत में रखने का कोई पेशेवर/विपक्ष है?ऑब्जेक्ट में वर्चुअल फ़ंक्शन टेबल पॉइंटर का स्थान

+0

Objdump उपयोगिता से vptr (वर्चुअल टेबल उर्फ ​​VTABLE को पॉइंटर) पुनर्प्राप्त करने के संभावित डुप्लिकेट?] (Http://stackoverflow.com/questions/10549311/retrieving-vptrpointer-to-virtual-table-aka-vtablefrom- the objdump-utility) – iammilind

उत्तर

7

वर्चुअल फ़ंक्शन तालिका का केवल अस्तित्व संकलक निर्भर है (लेकिन सभी कंपाइलर करते हैं), और स्थान या तो अनिवार्य नहीं है ... सभी कंपाइलरों में मुझे विवरण पता है, vptr वस्तु की शुरुआत में संग्रहीत किया जाता है। कारण यह है कि यह एक समान स्थान प्रदान करता है। एक वर्ग पदानुक्रम पर विचार करें:

struct base { 
    T data; 
    virtual void f(); 
}; 
struct derived : base { 
    T1 data; 
    virtual void g(); 
}; 

vptr वस्तु के अंत में जमा हो गया था, तो यह पूरा प्रकार base के ऑब्जेक्ट के लिए sizeof(T) बाइट्स के बाद किया जाएगा। अब जब आपके पास पूर्ण प्रकार derived का ऑब्जेक्ट है, तो base उप ऑब्जेक्ट का लेआउट पूर्ण base ऑब्जेक्ट के लेआउट के साथ संगत होना चाहिए, इसलिए vptr को ऑब्जेक्ट के अंदर अभी भी sizeof(T) बाइट्स होना चाहिए, जो कहीं कहीं होगा शुरुआत से derived ऑब्जेक्ट (sizeof(T) के बीच, sizeof(T1) अंत से पहले)। तो यह अब ऑब्जेक्ट के अंत पर नहीं होगा।

इसके अतिरिक्त, एक this सूचक को देखते हुए, एक आभासी कॉल vtable, जो मूल रूप से vptr अपसंदर्भन है के माध्यम से एक अविवेक, जोड़ने की आवश्यकता है एक ऑफसेट और स्मृति स्थान में संग्रहीत करने के लिए कूद। यदि vptr ऑब्जेक्ट के अंत में संग्रहीत किया गया था, तो प्रत्येक वर्चुअल कॉल के लिए को संदर्भित करने से पहले this में अतिरिक्त अतिरिक्त होगा।

+0

सिद्धांत में आप बेस-क्लास सबोबजेक्ट और पूर्ण ऑब्जेक्ट के अंत में Vptr दोनों को प्राप्त कर सकते हैं। यह कुछ समझ में आएगा: वर्चुअल फ़ंक्शंस के लिए 'व्युत्पन्न' vptr है जो 'बेस' में दिखाई नहीं देता है। लेकिन प्रति ऑब्जेक्ट ओवरहेड इतना अच्छा नहीं है। – MSalters

+0

ग्रेट स्पष्टीकरण !!! –

4

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

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