2010-01-31 15 views
6

सर आदरणीय!कैसे C++ बहुरूपता आंतरिक रूप से लागू करता है?

मैं आपको बता देना चाहिए कि क्या मुझे पता है और मैं क्या पूछा सवाल के बारे में इतना है कि आप मेरी समझ के कमजोर क्षेत्र पता कर सकते हैं पता नहीं है।

मुझे पता है कि C++ Vtable का उपयोग करके पॉलीमोर्फिज्म लागू करता है जो पॉइंटर्स वर्ग के वर्चुअल फ़ंक्शन पर प्रत्येक पॉइंटर पॉइंट्स है, पदानुक्रम में प्रत्येक वर्ग में एक vtable है। अब लगता है कि मैं निम्नलिखित वर्ग

class person 
{ 
    char name[20]; 
public: 
    person(char* pname) 
    { 
     strcpy(name,pname); 
    } 

    virtual void show() 
    { 
     cout<<"inside person show method, Name: "<<name; 
    } 
}; 

class teacher:public person 
{ 
    int scale; 

    teacher(char*pname, int s):person(pname) 
    { 
     scale=s; 
    } 

    void show() 
    { 
     cout<<"inside the teacher show method, Scale: "<<scale; 
    } 
}; 

अब लगता है मुख्य प्रोग्राम

person *ptr; 
ptr=new teacher(16,"Zia"); 
ptr->show(); 

अब मैं कर रहा हूँ इस बिंदु पर भ्रमित में मैं लिखना है, कॉल आधार वर्ग के शो समारोह के लिए जाना जाएगा, अब यह एक आभासी समारोह तो यह inturn approprite फ़ंक्शन को कॉल करने के रूप में। मुझे पता है कि मैं यहाँ गलत हूँ। मैं उलझन में हूं कि कॉल का अनुक्रम क्या होगा। Vtable की भूमिका क्या है और यह कैसे काम करती है विस्तृत करें।

+2

"सम्मानित सर"? गंभीरता से? यह "सम्मानित सर * एस * होना चाहिए!" चूंकि हम बहुत से हैं ...;) मुझे हमेशा आश्चर्य होता है कि कुछ उपयोगकर्ता मानदंडों के साथ क्यों शुरू करते हैं, यह थोड़ा पुरातन है। – Spoike

+0

ज़िया, कृपया मार्कडाउन सिंटैक्स सीखें: http://stackoverflow.com/editing-help – avakar

+0

@ ज़िया यू रहमान: qn http://stackoverflow.com/questions/2092283/how-functions-are-resolved पर एक नज़र डालें -by-compiler, जो बताता है कि जब कंपाइलर एक पॉलीमोर्फिक कॉल करता है और जब यह प्रत्यक्ष कॉल होने जा रहा है .. –

उत्तर

6

मुझे लगता है कि आप स्टैनले B लिप्पमैन की पुस्तक "Inside C++ object model" की ओर ध्यान आकर्षित करना चाहिए।

अपनी कक्षाओं के लिए आंतरिक प्रस्तुति के लिए देखो की सुविधा देता है:

व्यक्ति और शिक्षक

|---------------| +---> |------------------------| 
| name   | |  | "type_info" for person | 
|---------------| |  |------------------------| 
|__vptr__person |--+  | "person::~person"  | 
|---------------|  |------------------------| 
person p;    | "person::show"   | 
         |------------------------| 

|----------------| +---> |-------------------------| 
|person subobject| |  | "type_info" for teacher | 
|----------------| |  |-------------------------| 
|__vptr__teacher |--+  | "teacher::~teacher"  | 
|----------------|  |-------------------------| 
teacher t;    | "teacher::show"   | 
          |-------------------------|    

सामान्य में के लिए

वर्चुअल टेबल, हम में से प्रत्येक के मंगलाचरण में वस्तु ptr पतों का सही प्रकार पता नहीं है प्रदर्शन()। हम जानते हैं, तथापि, कि ptr के माध्यम से हम आभासी वस्तु के वर्ग के साथ जुड़े तालिका को एक्सेस कर सकते हैं।

हालांकि हम इस शो के जो उदाहरण() को लागू करने की पता नहीं है, हम जानते हैं कि प्रत्येक उदाहरण के पता स्लॉट 2.

में निहित है यह जानकारी संकलक आंतरिक

(*ptr->vptr[ 2 ])(ptr); 
में कॉल को बदलने के लिए अनुमति देता है

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

+0

उन्होंने –

+0

हां हालांकि अपने विनाशक वर्चुअल को नहीं बनाया। मुझे लगता है कि ज़िया यू रहमान का एवर होगा: "प्रिय महोदय, यह पूरा कोड नहीं है, मैंने केवल उस कोड को पोस्ट किया है जिसमें समस्या है।"; –

+0

ओहू हाँ महोदय! आप सही हैं, मैं केवल संबंधित कोड पोस्ट करता हूं। क्योंकि लोग लंबे कोड पढ़ने से नफरत करते हैं। और हाँ आपका जवाब पूरी तरह से सहायक है, धन्यवाद। –

8

show के बाद से person कक्षा में virtual घोषित किया जाता है, संकलक हार्ड-कोड नहीं ऐसा विधि कॉल एक गैर आभासी विधि के लिए क्या करना होगा, यह बजाय वि तालिका में एक देखने के क्रम को पुनः प्राप्त करने में संकलन होगा सही कार्य

तो ptr->show() जिसका अर्थ है "खोज समारोह सूचक है कि विधि show से मेल खाती है और यह अमल" ptr->vtable['show']() के रूप में संकलित किया जाएगा।

कार्यावधि में के बाद से, वर्ग teacher का एक उद्देश्य के लिए ptr अंक, show के लिए vtable स्लॉट वर्ग teacher में विधि show के लिए सूचक होता है। यही कारण है कि सही विधि निष्पादित की जाती है।

वास्तव में, वि तालिका में देखने तार का उपयोग कर, लेकिन क्रम में जितनी जल्दी संभव के रूप में होने के लिए सांख्यिक विधि पहचानकर्ता का उपयोग नहीं किया जाता है।

4

C++ भाषा बहुरूपता कार्यान्वयन को परिभाषित नहीं करता, यहां तक ​​कि vtable नहीं। यह कंपाइलर्स पर निर्भर है।
एक संभावित क्रियान्वयन Vincent Robert ने उल्लेख किया है।

3

The Standard कैसे बहुरूपता लागू करता है के बारे में कुछ नहीं कहते हैं। एक वर्ग एक vtbl और एक वस्तु एक vptr सबसे लोकप्रिय तरीका है। मुझे आशा है कि निम्नलिखित स्यूडोकोड उपयोगी होगा।

typedef struct { 
    void (*show)(void* self); 
    // more 

} person_vtbl; 

typedef struct { 
     person_vtbl* vtbl; 
     char   name[20]; 
} person; 

void person_show(void* self) { 
     cout<<"inside ... "<<static_cast<person*>(self)->name; 
} 
// more 

static person_vtbl person_vtbl_ = { &person_show }; // vtbl for person class 

void person_ctor(void* self, char const* name) { 
     person* p = static_cast<person*>(self); 
     strcpy(p->name, name); 
     p->vtbl = &person_vtbl // vptr of person object 
} 

typedef struct { 
    person base; 
    int scale; 
} teacher; 

void teacher_show(void* self) { 
     cout<<"inside the tearch ... "<<static_cast<teacher*>(self)->scale; 
} 
static person_vtbl teacher_vtbl_ = { &teacher_show }; 

void teacher_ctor(void* self, char const* name, int s) { 
     teacher* t = static_cast<teacher*>(self); 
     person_ctor(&t->base, name);  // construct base part 
     t->scale = s;     // construct teacher part 
     t->vtbl = &teacher_vtbl_;  // vptr of teacher object 
} 

// construct teacher : 
// person* ptr = new teacher("Zia", 16); 

teacher* tmp = static_cast<teacher*>(malloc(sizeof *tmp); 
teacher_ctor(tmp, "Zia", 16); // vptr of tmp points to teacher_vtbl_ 
person* ptr = &tmp->base; 

// call virtual function though pointer 
// ptr->show() 

ptr->vptr->show(ptr); // call teacher_show(ptr); 
संबंधित मुद्दे