2012-01-19 14 views
7

Let में वर्चुअल प्वाइंटर की संख्या हम कार्यक्रम नीचे है कहना:आभासी मेज और एक सी ++ प्रोग्राम

class A 
{  public: 
     virtual fun(){}; 
}; 
class B:public A 
{  public: 
    virtual fun(){}; 
}; 
int main() 
{ 
    A a1; 
    B b1; 
} 

मेरा प्रश्न, कितने vtables और कितने vptrs बनाया जाएगा है जब हम इस कार्यक्रम चलाने के?

उत्तर

9

इसका भारी कार्यान्वयन निर्भर है, लेकिन आम तौर पर आपको प्रति वर्ग एक vtable ऑब्जेक्ट मिलेगा जिसमें कोई वर्चुअल फ़ंक्शंस (वर्चुअल फ़ंक्शंस वाले क्लास या बेस की आवश्यकता नहीं होती है), और कक्षा के प्रति एक vptr प्रति ऑब्जेक्ट vtable (कक्षा के vtable पर इशारा करते हुए)।

यदि आपके पास एकाधिक विरासत और वर्चुअल बेस क्लासेस हैं तो चीजें अधिक जटिल हो जाती हैं - जिन्हें कई तरीकों से लागू किया जा सकता है। कुछ कार्यान्वयन अतिरिक्त बेस क्लास प्रति अतिरिक्त vtable का उपयोग करते हैं (इसलिए आप प्रति वर्ग प्रति बेस क्लास के साथ समाप्त होते हैं), जबकि अन्य इसमें एक अतिरिक्त vtable का उपयोग करते हैं जिसमें अतिरिक्त जानकारी होती है। इसके परिणामस्वरूप प्रति ऑब्जेक्ट एकाधिक vptrs की आवश्यकता हो सकती है।

virtual बी में कीवर्ड अप्रासंगिक है - यदि फ़ंक्शन बेस क्लास में वर्चुअल है, तो यह व्युत्पन्न कक्षाओं में वर्चुअल होगा।

+0

अब अगर मैं नीचे अपना पीजीएम संशोधित करता हूं: मैं व्युत्पन्न वर्ग से वर्चुअल कीवर्ड को हटा देता हूं। अब कितने vtables बनाया जाएगा? – CodeCodeCode

+2

@Pal - कोई फर्क नहीं पड़ता, फ़ंक्शन अभी भी वर्चुअल है। –

+0

@ बो पर्सन: फ़ंक्शन आभासी है, लेकिन क्या व्युत्पन्न कक्षा के लिए भी एक vtable बनाया जाएगा? – CodeCodeCode

3

ध्यान दें कि यह कड़ाई से कार्यान्वयन निर्भर है।
सी ++ मानक vptr या vtable की बात नहीं करता है, वर्चुअल तंत्र को कंपाइलरों के लिए कार्यान्वयन विवरण के रूप में छोड़ दिया जाता है। तो व्यावहारिक रूप से, कंपाइलर इसे vptr या vtable का उपयोग किए बिना कार्यान्वित कर सकते हैं। हालांकि, लगभग सभी ज्ञात कंपाइलर इसे vptr और vtable का उपयोग करके कार्यान्वित करते हैं।

प्रत्येक वर्ग अपने स्वयं के आभासी मेज होगा:

अपने सवाल का जवाब देने से ऊपर को देखते हुए।
जबकि प्रत्येक ऑब्जेक्ट का अपना वर्चुअल पॉइंटर होता है।

+0

उत्तर के लिए धन्यवाद अल, अब मुझे थोड़ा उलझन में मिला है। कृपया मुझे बताएं कि क्या मैं कक्षा बी (व्युत्पन्न) से वर्चुअल कीवर्ड को हटाता हूं तो कितने vtables बनाए जाएंगे? – CodeCodeCode

+0

@CodeCodeCode यदि आप कक्षा बी (व्युत्पन्न) से वर्चुअल कीवर्ड को हटाते हैं तो कितने vtables बनाए जाएंगे? उत्तर आधार के लिए वही 2 वही रहता है। –

+0

@aloksave मैंने कहीं पढ़ा है कि चूंकि बेस क्लास में वर्चुअल फ़ंक्शन है, उसके पास एक वीपीटीआर होगा और इसे व्युत्पन्न वर्ग में विरासत में मिला है लेकिन व्युत्पन्न क्लास vtable को इंगित करता है। क्या आप उस पर मदद कर सकते हैं। –

7

असल में, class B (vftables) और 2 vfptrs, a1 के लिए एक और b1 लिए एक-एक 2. class A के लिए एक,।

हालांकि, यह मानक अनिवार्य नहीं है, इसलिए आपके पास कोई भी नहीं हो सकता है। (आमतौर पर कार्यान्वयन vftables उपयोग करते हैं, लेकिन इसकी नहीं सौंपा।

नोट @R। पर, आप, कोई ऑब्जेक्ट का निर्माण होगा ताकि कोई vfptrs। अनुकूलन के साथ Martinho फर्नांडीस

+0

+1 वास्तव में प्रश्न की तरह संख्याओं को बताते हुए –

12

इस कार्यक्रम वास्तव में की तरह होना करने के लिए अनुकूलित किया जा सकता है इस एक:

int main(){} 

तो, "कोई नहीं" एक संभावना है

+0

मैं मजाकिया के लिए +1 करना चाहता हूं, लेकिन ... –

+0

necesarrily नहीं, आपके पास 2 या 1000 हो सकते हैं (इसे ऑप्टिमाइज़ करने के लिए अनिवार्य नहीं है)। लेकिन विचार के लिए +1 :) –

+0

int main() {} एक सी ++ प्रोग्राम लिखने के लिए पर्याप्त है। कोड की किसी अन्य पंक्ति की कोई ज़रूरत नहीं है। :) – CodeCodeCode

2

virual तालिका कम से कम 1 आभासी समारोह बेस वर्ग, किसी भी तरह से करने के लिए जो विरासत में मिला दिया जाएगा में वहाँ केवल अगर बनाया जाएगा। व्युत्पन्न कक्षाएं। इससे कोई फर्क नहीं पड़ता कि आप व्युत्पन्न कक्षा बी से वर्चुअल कीवर्ड को हटाते हैं क्योंकि पहले से ही आपके पास ए में वर्चुअल मजेदार() है, इसलिए वर्चुअल टेबल की संख्या 2 (प्रति वर्ग आधार के रूप में) और वर्चुअल की संख्या होगी पीटीआर भी प्रति ऑब्जेक्ट आधार के रूप में 2 होगा।ए --- v_ptr * के लिए VATABLE *, ए :: मजेदार()

& बी --- V_ptr * (जिसे ए से विरासत में मिला था) के लिए VTABLE, बी :: मजेदार()/* बी दोनों को एक्सेस है :: मजेदार & बी का मज़ा(), लेकिन चूंकि हमने ए :: मजेदार() का उल्लेख किया है क्योंकि वर्चुअल बी की आभासी तालिका फ़ंक्शन के सबसे व्युत्पन्न संस्करण से भरा है, मजेदार(), जो बी :: मजेदार() के अलावा कुछ भी नहीं है। उम्मीद है कि यह साफ करता है उर शक

0

वहाँ वर्ग एक और वर्ग बी के लिए एक के लिए 2 vtables, एक हो जाएगा। और 3 vptrs होगा, एक 1 और दो में बी 1 (vtableकक्षा ए और अन्य vtableकक्षा बी) पर इंगित करता है।

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