2015-06-30 10 views
5

मैंने vtable के बारे में पढ़ा है और बेस क्लास पॉइंटर्स के लिए अवधारणा को समझ लिया है जो बेस और व्युत्पन्न क्लास ऑब्जेक्ट्स को इंगित करता है। क्या कोई इस मामले को समझा सकता है कि कैसे बेस क्लास और व्युत्पन्न कक्षा वस्तुएं हैं और व्युत्पन्न क्लास ऑब्जेक्ट बेस क्लास ऑब्जेक्ट को सौंपा गया है। नीचे दिए गए उदाहरण में प्रकरण 3आधार और व्युत्पन्न वस्तुओं का उपयोग कर वर्चुअल फ़ंक्शन

#include <iostream> 
#include <exception> 
using namespace std; 


class Base 
{ 
public: 
    virtual void function1() { cout<<"Base - func1"<<endl; } 
    virtual void function2() { cout<<"Base - func2"<<endl; } 
}; 

class Derived1: public Base 
{ 
public: 
    virtual void function1() { cout<<"Derived1 - func1"<<endl; } 
}; 

class Derived2: public Base 
{ 
public: 
    virtual void function2() { cout<<"Derived2 - func2"<<endl; } 
}; 

int main() 
{ 
    // Case 1 
    Base* B1 = new Derived1(); 
    B1->function1(); 
    B1->function2(); 

    // Case 2 
    cout<<endl; 
    Base* B2 = new Derived2(); 
    B2->function1(); 
    B2->function2(); 

    // Case 3 
    cout<<endl; 
    Base B3; 
    Derived1 D1; 
    B3=D1; 
    B3.function1(); 
    B3.function2(); 
} 

उत्पादन:

Derived1 - func1 
Base - func2 

Base - func1 
Derived2 - func2 

Base - func1 
Base - func2 
+1

आपने 'बी 3' के लिए स्लाइसिंग की है। – Jarod42

+1

बस यह बताते हुए कि आपके वर्ग डी 1, डी 2 का नामकरण और फिर आपके चर बी 1, बी 2, बी 3 भ्रमित हो सकते हैं। वेरिएबल नामों के लिए कम से कम उपयोग के मामले में यह स्पष्ट करने के लिए कि वे कक्षा के नाम नहीं हैं। आपके कोड में कुछ सम्मेलनों का उपयोग करने से आप और जो भी इसे पढ़ सकते हैं, आपकी मदद कर सकते हैं। – aslg

+2

आपको "vtable" शब्द का उपयोग नहीं करना चाहिए जबतक कि आप एक कार्यान्वयन के बारे में बात नहीं कर रहे हैं जो वर्चुअल फ़ंक्शंस को लागू करने के लिए विशेष रूप से vtables तकनीक का उपयोग करता है। सी ++ भाषा में स्वयं vtables की धारणा नहीं है। –

उत्तर

2

B3=Derived;वस्तु टुकड़ा करने की क्रिया का एक उदाहरण है ... केवल आधार वर्ग डेटा सदस्यों को सौंपा जाता है, और vtable सूचक के लिए जारी है बेस क्लास फ़ंक्शंस को इंगित करें।

आपको स्लाइसिंग से बचना चाहिए - यह खतरनाक हो सकता है (this answer को स्पष्टीकरण के लिए देखें)। अब आप अवधि, आप आसानी से वस्तु टुकड़ा करने की क्रिया पर पढ़ने के बहुत सारे मिल जाएगा पता है ....

0
Base B3; 
D1 Derived; 
B3=Derived; //There is called default assignment operator 

ऐसा परिभाषित किया गया है:

Base& operator=(const Base &objectToCopy) {...} 

ऑपरेटर प्रकार Base का एक तर्क लेता है, इसलिए D1 प्रकार की वस्तु Base प्रकार की वस्तु के रूप में माना जाता है। इसका मतलब है कि असाइनमेंट ऑपरेटर केवल Derived के फ़ील्ड देखता है जो कक्षा Base में हैं। हालांकि, सूचक vtable (जो तकनीकी रूप से एक छिपे हुए क्षेत्र है) अभी भी प्रतिलिपि नहीं है, क्योंकि यह हमेशा निर्माता में बना रहता है और यह वास्तविक वस्तु प्रकार से स्थायी रूप से जुड़ा हुआ है।

+1

ऑपरेटर टाइप 'कॉन्स्ट बेस एंड' का तर्क लेता है, जो * * * निश्चित रूप से कुछ भी 'बेस' में परिवर्तित नहीं करता है। ऑपरेशन के दौरान रूपांतरण के दौरान रूपांतरण असाइनमेंट के दौरान होता है। – EJP

+0

@EJP मुझे खेद है। मैंने बुरा व्यक्त किया। क्या यह अब अच्छा है? –

+0

अभी भी तर्क प्रकार (जिसे आपने अभी भी गलत बताया है) से कोई लेना देना नहीं है। इसे ऑपरेटर विधि के अंदर क्या होता है इसके साथ करना है। – EJP

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