वेलकम टू मॉड्यूल(module) 26 टू प्रोग्रामिंग ऑफ सी ++। हमने C ++ में इनहेरिटेंस(Inheritance) स्ट्रक्चर(structure) देखी है। हम ऑब्जेक्ट(object)-ओरिएंटेड(oriented) कार्यान्वयन का समर्थन करने के लिए सी + + की संभवतः सबसे शक्तिशाली विशेषता में से एक पर ध्यान देंगे, जिसे आमतौर पर बहुरूपता(polymorphism) के नाम से जाना जाता है। लेकिन इससे पहले कि हम बहुरूपता(polymorphism) की चर्चा के संदर्भ में गहराई से जा सकें, हमें कास्टिंग(casting) के संदर्भ में कुछ और समझ के साथ खुद को तैयार करने की आवश्यकता है जो एक क्लास(class) पदानुक्रम(hierarchy) में हो सकती है। और स्थैतिक(static) और गतिशील(dynamic) बिंडिंग(binding) के बीच मुख्य अंतर। तो, यह गतिशील(dynamic) बिंडिंग(binding) चर्चा कुछ मॉड्यूल(module) को कवर करेगी और यह पहला है और हमें C ++ में बहुरूपता(polymorphism) की कुल समझ का नेतृत्व करेगा। इसलिए, रूपरेखा कास्टिंग(casting) और स्थैतिक(static) और गतिशील(dynamic) बिंडिंग(binding) है जो आपकी हर स्क्रीन के बाईं ओर उपलब्ध होगी। तो चलिए, हम कास्टिंग(casting) के बारे में बात करते हैं। हम सभी कास्टिंग(casting) जानते हैं, आप सभी सी जानते हैं। इसलिए, आपको पता है कि कास्टिंग(casting) मूल रूप से एक प्रकार के मूल्य का प्रदर्शन किया जाता है, कुछ प्रकार का उपयोग किया जाता है, कुछ अन्य प्रकार का उपयोग किसी अन्य प्रकार के संदर्भ में किया जाता है। इसलिए, उदाहरण के लिए, यहाँ i एक पूर्णांक(integer) मान चर है, d एक दोहराdouble) चर है और मैं d / i लिख रहा हूँ। इसलिए, यदि मैं d कहता हूं तो यदि मैं कहता हूं / तो इस का अर्थ / फ्लोटिंग(floating) पॉइंट(point) संख्याओं का एक विभाजन है। तो, यहाँ जो अपेक्षित है वह एक दोहराdouble) मूल्य भी है लेकिन मैंने जो प्रदान किया है, मैंने पूर्णांक(integer) मूल्य प्रदान किया है। तो, यह अभी भी सी में काम करता है यह कैसे काम करता है? इसलिए कुछ प्रक्रिया करनी होगी जिसके द्वारा इस पूर्णांक(integer) मान को दोहराdouble) मान में परिवर्तित किया जाता है और फिर उपयोग किया जाता है। तो, यह तंत्र कास्टिंग(casting) का तंत्र है जिसे मैं डबल करने के लिए डाला जाता है और फिर इसका उपयोग किया जाता है। तो, यह एक सरल धारणा है जिसे हमने देखा है और सी में इसे विशेष रूप से विशेष रूप से मिश्रित मोड ऑपरेशन(mixed mode operation) के रूप में संदर्भित किया जाता है जिसे हम सभी जानते हैं। अब, चलिए शुरुआत को थोड़ा और विकसित करते हुए आगे बढ़ते हैं, हम जानते हैं कि कास्टिंग(casting) निहित हो सकती है या यह स्पष्ट हो सकता है। उदाहरण के लिए, पहले देखो कि किस प्रकार के वैरिएबल में i एक इंट वैरिएबल है, डी एक डबल वेरिएबल है और पी एक पॉइंटर (pointer) वेरिएबल पॉइंटर (pointer) टू डबल है। इसलिए, अगर मैं i से d तक असाइनमेंट करता हूं, तो यह दोहरा(double) है और यह int है। तो, निश्चित रूप से वे एक ही प्रकार के असाइनमेंट के लिए संभव नहीं हैं, लेकिन स्पष्ट रूप से यह पूर्णांक(integer) को डबल कास्ट(cast) करेगा और मुझे ऐसा करने की अनुमति देगा। मैं रिवर्स को दोहराdouble) सकता हूं जिसे i को सौंपा जा रहा है इसे भी अनुमति दी जाएगी, लेकिन साधारण कारण के लिए एक चेतावनी के साथ क्योंकि डबल एक बहुत बड़ा डेटा प्रकार है, जबकि int एक छोटा डेटा प्रकार है, इसलिए कुछ डेटा खो जाएगा। इसके विपरीत, मैं उपयोग कर सकता हूं जिसे सी स्टाइल कास्टिंग(casting) कहा जाता है जो उपलब्ध मूल्य से पहले आवश्यक प्रकार को कोष्ठक में डाल दिया जाता है और इसका उपयोग किया जाता है, इसे स्पष्ट कास्टिंग(casting) के रूप में जाना जाता है। और अब कंपाइलर(compiler) चिल्लाएगा नहीं। तो, आप देख सकते हैं कि अगर मैं कुछ करने की कोशिश करता हूं जैसे कि पी एक पॉइंट(point)र है और मैं एक पूर्णांक(integer) है, अगर मैं पी को असाइन करना चाहता हूं तो यह एक त्रुटि है कि आप निश्चित रूप से एक डबल पॉइंट(point)र नहीं ले सकते हैं और इसे इंट के रूप में उपयोग कर सकते हैं। लेकिन अगर मैं स्पष्ट रूप से कास्ट(cast) करता हूं तो सी कंपाइलर(compiler) इसकी अनुमति देगा। ये कास्टिंग(casting) का मूल नियम हैं। आइए अब हम इसे C ++ तक विस्तारित करने का प्रयास करते हैं। इसलिए, पहले हम केवल इंट(int), पॉइंटर (pointer), डबल वगैरह के प्रकारों के बारे में बात कर रहे थे। अब, मेरे पास दो क्लास(class) ए और बी हैं और मेरे पास दो वस्तुएं हैं, मेरे पास दो पॉइंटरस (pointers), हैं एक प्रकार A है और एक बी प्रकार का है जो ए के पते को रखेगा, और बी का पता को रखेगा। असाइनमेंट यह एक कास्टिंग(casting) त्रुटि है क्योंकि यह असाइनमेंट क्या कह रहा है? यह कह रहा है कि बी को a सौंपा गया एक मतलब a है ;; हम सभी जानते हैं कि यह अब ऑपरेटर असाइनमेंट b है। तो, इसका मतलब यह है कि यह क्लास(class) ए, जिसके पास यह है, यह क्लास(class) ए के अंतर्गत आता है, जिसके पास एक ऑपरेटर होता है `= ' जो टाइप बी का एक ऑपरेंड लेता है, जो मौजूद नहीं है। यदि हम स्पष्ट रूप से कास्ट(cast) को डालने का प्रयास करते हैं, तो यह भी विफल हो जाएगा क्योंकि कोई स्पष्ट कास्ट(cast) परिभाषित नहीं है। इंट की तरह नहीं है, डबल जहां आप जानते हैं कि इंट को डबल या डबल से इंट में कैसे कन्वर्ट किया जाए। इसलिए, यदि आप उन्हें पाठ्यक्रम के रिवर्स तरीके से करने की कोशिश करते हैं, तो यह विफल हो जाएगा। यदि आप दो प्रकार के पॉइंटर्स(pointers) पॉइंटर(pointer) को एक पॉइंटर(pointer) टू बी में डालने का प्रयास करते हैं तो यह विफल हो जाएगा, दूसरी दिशा यह भी विफल हो जाएगी। इसलिए, ये सभी विफलताएं हैं क्योंकि आपको ऐसा करने की अनुमति नहीं है। केवल एक चीज जो आपको मजबूर कर सकती है वह है आप & b, & b टाइप B * ले सकते हैं और इसे A * करने के लिए बाध्य कर सकते हैं। यही कारण है कि आप असंबंधित वर्गों के पोइंटर(pointer) को दूसरे में बदल सकते हैं, लेकिन एक मजबूर तरीके से। स्वाभाविक रूप से, आप ऐसा नहीं कर सकते हैं p = q की अनुमति नहीं है। यह B * का, यह A * का है। आप एक असाइनमेंट नहीं बना सकते, आप उपयोग नहीं कर सकते। लेकिन अगर आप जबरदस्ती कहते हैं कि B * A * पॉइंटर(pointer) में बदल जाता है, तो आप यह असाइनमेंट बना सकते हैं। इसका सममित भी काम करेगा। इसलिए, यह मूल रूप से है कि जब हम C ++ को शुरू करते हैं तो कक्षाओं के बीच कास्टिंग(casting) की कहानी होती है। अब, यदि हम बलपूर्वक कास्टिंग(casting) करते हैं जैसा कि हमने अभी असंबंधित वर्गों के बीच देखा था, तो परिणाम खतरनाक हो सकते हैं वास्तव में बहुत अप्रत्याशित हो सकते हैं। इसलिए, मेरे पास सिर्फ समान दो क्लास(class) हैं। अब, मैंने अभी डेटा सदस्यों को सार्वजनिक रूप से रखा है। मैं आपको सिर्फ दिखाना चाहता हूं। इसलिए, इन डेटा सदस्यों को आरंभीकृत किया गया है और मेरे पास टाइप पी का एक पॉइंटर(pointer) है जो एक प्रकार A रखता है जो A पते को क्यू रखता है और मैं मूल्यों को प्रिंट करता हूं निश्चित रूप से मान सही ढंग से मुद्रित होते हैं। a. ; p -> i मूल रूप से a.i है जो 5 है, q -> d 7.2 है। अब, मान लीजिए कि मैंने बलपूर्वक इसे कास्ट(cast) किया है। इसलिए, अगर मैंने जबरदस्ती कास्ट(cast) है तो कहा है कि यह वही है जो मैं चाहता हूं। क्या यह ब ऑब्जेक्ट(object) है और पॉइंटर(point) को मैंने एक पॉइंटर(point) के रूप में कास्ट(cast) किया है और फिर मैं यह करने की कोशिश कर रहा हूं। यह वही है जो यह प्रिंट करता है। यदि आप यह कोशिश करते हैं तो यह आवश्यक नहीं है कि यह इसे प्रिंट करेगा। मेरे सिस्टम में इसने इसे प्रिंट किया है, लेकिन यह निश्चित रूप से कुछ कचरा प्रिंट करेगा। ये क्यों हो रहा है? ऐसा इसलिए हो रहा है क्योंकि यदि आप किसी वस्तु को इंट के रूप में देखते हैं। बता दें कि हम 32 बिट सिस्टम पर हैं। तो, int में 4 बाइट्स होते हैं जिसमें यह मान 5 लिखा होता है। एक ब ऑब्जेक्ट(object) में मेरे पास एक डबल है जिसमें संभवतः 8 बाइट्स हैं। अब, अगर मैं पॉइंटर(point) पी लेता हूं जो टाइप ए का है; इसका मतलब है कि, पॉइंटर(point) अगर मैं p ->i लिखता हूं, तो यह संकलक हमेशा जानता है कि उसे 2 और एक प्रकार की वस्तु चाहिए ताकि वह लगातार 4 बाइट्स ले सके और इसे पूर्णांक(integer) बना सके। अब, यही मैंने उल्लंघन किया है। मैंने क्या किया है? मैंने वास्तव में पी लिया है और इसे बी पते पर इंगित करता हूं। अब यहाँ 8 बाइट्स में जो लिखा गया था वह 7.2 लिखा गया था, लेकिन p जानता है कि यह a प्रकार का है। तो, यह जानता है कि इसे 4 बाइट्स पढ़ना है और लगता है कि यह पूर्णांक(integer) है। तो, यह लगता है कि 7.2 का फ्लोटिंग(floating) पॉइंट(point) प्रतिनिधित्व मनमाना संभवतः पहले चार बाइट्स पढ़ता है और यह सोचना शुरू कर देता है कि यह एक पूर्णांक(integer) है और इसे पूर्णांक(integer) के रूप में प्रिंट करता है। जब मैं रिवर्स के बारे में सोचता हूं जब मैं रिवर्स करता हूं तो मैं क्या कर रहा हूं? मेरे पास q पोइंटर(pointer) है जो b प्रकार की ओर इशारा करता है। इसलिए, अगर मैं q -> d करता हूं तो यह उम्मीद करता है कि 8 बाइट्स एक डबल का प्रतिनिधित्व करेंगे। अब, मैंने इस a ऑब्जेक्ट(object) को q पॉइंट कर रहा है, जिसका अर्थ है कि यह वास्तव में 8 बाइट्स पढ़ रहा है, जिनमें से पहले 4 बाइट्स 5 का पूर्णांक(integer) प्रतिनिधित्व है। अगले 4 बाइट, भगवान जानता है कि क्या है। यह स्मृति का अमान्य हिस्सा है, यह वहाँ जाता है मूल्य व्याख्या को यह एक अस्थायी संख्या के रूप मे लेता है और प्रिंट करता है। तो, यह मूल समस्या है कि कास्टिंग(casting) मे आपको मिल सकती है। तो, जबरदस्ती कास्टिंग(casting) एक खतरनाक चीज है। अब, देखते हैं कि यदि आप इसे पदानुक्रम(hierarchy) पर करने का प्रयास करते हैं तो कास्टिंग(casting) कैसा दिखेगा। तो, हमारे पास क्लास(class) ए है और क्लास(class) बी है जो ए का एक विशेषज्ञता है। इसलिए, मेरे पास दो क्लास(class) प्रकार के दो संकेत हैं। अब पहले जब वे प्रकार जहाँ असंबंधित थे, एक प्रकार के पॉइंटर(point) को दूसरे के पॉइंटर(point) में असाइन करना संभव नहीं था, लेकिन अब मैं pb to pa असाइन कर सकता हूं, और इसकी अनुमति होगी। लेकिन अगर मैं pb को रिवर्स असाइन करने के लिए pb करने की कोशिश करता हूं तो इसकी अनुमति नहीं होगी। वजह साफ है। यदि मेरे पास A ऑब्जेक्ट(object) है और B ऑब्जेक्ट(object) के बारे में सोचता है, तो B ऑब्जेक्ट(object) के पास क्या है? यह A का एक स्पेशलाइजेशन है, इसलिए B ऑब्जेक्ट(object) में आंतरिक रूप से A ऑब्जेक्ट(object) होता है जो बेस ऑब्जेक्ट(object) है। तो, अगर मेरे पास एक प्रकार pa है, जो A प्रकार का पोइंटर(pointer) है, तो यह A प्रकार का पोइंटर(pointer) है। फिर, जब मैंने इसे pb असाइन किया, तो pb क्या था? pb B प्रकार का एक पोइंटर(pointer) है जो कि इस ओर पोइंटर(pointer) है। इसलिए, जब मैं यह मान लेता हूं और इसे A को देता हूं तो उसी क्षेत्र को p a से संदर्भित करता है। लेकिन, यह pa क्या जानता है, pa जानता है कि यह एक प्रकार का पोइंटर(pointer) है जिसका अर्थ है कि pa जानता है कि इसे एक A वस्तु मिलेगी। तो, यह क्या करेगा? यह बस नहीं लेगा B के विस्तारित भाग का संज्ञान नहीं ले पाएगा, लेकिन इसे मान्य A ऑब्जेक्ट(object) मिलेगा जो B ऑब्जेक्ट(object) का आधार भाग है और आपको केवल वह ऑब्जेक्ट(object) देगा। इसलिए, ऐसा करना काफी है। आपको बस उसी का एक सीमित दृश्य मिलता है। लेकिन अगर आप दूसरे तरीके से करने की कोशिश करते हैं, अगर हम pb लेने की कोशिश करते हैं और इसे A ऑब्जेक्ट(object) की तरफ इशारा करते हैं तो pb चीजों को पता होता है कि आधार भाग के रूप में A ऑब्जेक्ट(object) है और फिर और चीजें हैं। तो, यह सोचने की कोशिश करेंगे कि यह पूरी चीज बी ऑब्जेक्ट(object) है जो वास्तव में मौजूद नहीं है केवल ए ऑब्जेक्ट(object) मौजूद है। तो, यह कुछ खतरनाक होगा यह स्मृति के संदर्भ में उल्लंघन में मिलेगा। तो, यही कारण है कि इसकी अनुमति है। मुझे रंग बदलने दें जबकि यह अनुमति नहीं है। और जब हम ऐसा कर रहे हैं यदि मैं पदानुक्रम(hierarchy) आरेख पर वापस जाता हूं तो यह आरेख B ISA A है। जैसा कि मैं करता हूं कि मैं B या विशेष वस्तु की दिशा से सामान्यीकृत वस्तु की ओर बढ़ रहा हूं इसलिए मैं ऊपर जा रहा हूं। तो, हम कहते हैं कि यह अपकास्ट(upcast) है जिसकी अनुमति है। लेकिन अगर मैं नीचे जाने की कोशिश करता हूं, अगर मैं एक सामान्यीकृत वस्तु लेता हूं और सोचता हूं कि यह एक विशेष है, तो डाउनकास्ट(downcast) कहें जिसे मना करना होगा। बेशक, उसी उदाहरण में मैंने यह भी दिखाया है कि यदि आपके पास एक शून्य पोइंटर(pointer) है तो क्या होगा। निश्चित रूप से आप किसी भी प्रकार की वस्तुओं को ले सकते हैं और हाँ उस पते को शून्य पोइंटर(pointer) में रखते हैं जो कि होता है आप प्रकार खो देते हैं। इसी तरह, आप रिवर्स कर सकते हैं। उल्टा करने की कोशिश करें जो मुझे लगता है कि यहां एक टाइपो है जो ये टाइपो हैं मैं इसे बाद में प्रस्तुति में सही करूंगा। तो, इसका मतलब यह है कि यदि p को pv दिया गया है या pb को pv दिया गया है तो ये सभी त्रुटि होगी क्योंकि pa एक शून्य* है pv एक शून्य* पोइंटर(pointer) है। तो, यह पता नहीं है, यह कहाँ इंगित करता है? यह पता नहीं है कि इसे कितने क्षेत्रों में किस आकार को इंगित करना चाहिए। इसलिए, यदि आप इसे लेते हैं और ए के रूप में व्याख्या करने की कोशिश करते हैं, तो निश्चित रूप से आपके पास हर तरह के खतरे हैं। तो, इनकी अनुमति नहीं दी जाएगी, लेकिन यह काफी ठीक है यदि आप वास्तव में किसी भी प्रकार के एक पॉइंटर(point) को लेते हैं और इसे एक शून्य पॉइंटर(point) में डालते हैं। बेशक, सी ++ में हम देखेंगे कि इसके लिए कोई भी उपयोग बुरी तरह से होगा। अब, अगर हम उपकास्टिंग(upcasting) की ओर देखते हैं, तो हम केवल डेटा सदस्यों के साथ कक्षा को बढ़ा सकते हैं और यदि हम देखते हैं कि यदि हम किसी वस्तु के लिए मान २ रखते हैं, तो वह डेटा भाग है एक A वस्तु का जिसका मूल्य 3 और 5 है। तो, यह एक वस्तु है जो 2 है। यह b वस्तु है जो 3 में है, एक भाग और 5। और फिर अगर हम उनके पते लेते हैं और खेतों को प्रिंट करने का प्रयास करते हैं। हम 2 और 3 प्राप्त करते हैं, 5। यह एक a ऑब्जेक्ट(object) को प्रिंट कर रहा है, यह बी ऑब्जेक्ट(object) को प्रिंट कर रहा है। अब, हम कहते हैं कि हमने उपकास्ट(upcast) किया है। यह एक उपकास्ट(upcast) की स्थिति है जिसे मैंने b का पता लिया है और इसे A के पॉइंटर(point) में डाल दिया है। तो, pa को देखने के लिए क्या मिलता है? Pa यहाँ इंगित कर रहा है, लेकिन उसे केवल a का ज्ञान है। तो, यह केवल इस भाग को देखने के लिए मिलता है। तो, क्या होता है अगर मैं pa -> dataA_ को प्रिंट करने की कोशिश करता हूं, तो यह प्रिंट करता है और आपको उम्मीद के मुताबिक 3 मिलता है, लेकिन अगर आप इस pa-> डेटा B_ को करने की कोशिश करते हैं यानी यदि आप इसे प्रिंट करने की कोशिश करते हैं तो निश्चित रूप से संकलक आपको एक त्रुटि देता है क्योंकि संकलक जानता है कि pa एक A प्रकार का पोइंटर(pointer) है जिसमें कोई डेटाबी_ सदस्य नहीं है और इसलिए, यह अनुमति नहीं दी जाएगी। इसलिए, यदि उपकास्ट(upcast) करते हैं तो ऐसी कोई स्थिति नहीं है जहां आप एक त्रुटि स्थिति में आ सकते हैं क्योंकि या तो आप कक्षा के आधार भाग तक पहुंचेंगे, जो कि केवल सीमित पहुंच बना रहा है जो ठीक है या आप और संकलक आपको उपयोग करने से प्रतिबंधित कर देंगे या विशेष क्लास(class) के किसी भी हिस्से तक पहुंचना जो वास्तव में मौजूद नहीं है। तो, upcasting सुरक्षित है। डाउनकास्टdown(cast) आप बहुत आसानी से तर्क दे सकते हैं कि डाउनकास्टिंग(downcasting) जोखिम भरा होगा। यह देखते हुए कि मैं सिर्फ स्थैतिक(static) और गतिशील(dynamic) बिंडिंग(binding) की मूल अवधारणा का परिचय दूं और यह धीरे-धीरे स्पष्ट हो जाएगा कि मैंने इसे शुरू करने से पहले कास्टिंग(casting) के बारे में चर्चा क्यों की? इसलिए, मेरी एक बहुत ही सरल स्थिति है। मुझे वापस लाल करने दो। तो, एक बहुत ही सरल स्थिति एक बेस क्लास है और एक विशेष व्युत्पन्न क्लास बी, क्लास डी है। हमने इसे पहले देखा है। तो, बेस क्लास में एक फंक्शन f () मेथडf () व्युत्पन्न क्लास इनहेरिट की गई है और फिर इस विधि को ओवरराइड किया गया है। उसके बारे में कुछ खास नहीं है। बेस क्लास में एक और फ़ंक्शन(function) जी () और व्युत्पन्न क्लास(class) है जो उस फ़ंक्शन(function) को भी ओवरराइड करता है। इसमें केवल अलग बात यह है कि फ़ंक्शन(function) जी के मामले में हमने एक और अतिरिक्त शब्द कीवर्ड वर्चुअल(virtual) लिखा है और हम देखेंगे कि व्यवहार कैसे बदलता है। तो, यह स्थिति हमेशा उस आरेख को ध्यान में रखें। इसलिए, मेरे पास एक निर्मित दो उदाहरण हैं और हमारे पास दो पोइन्तेर्स है pb और pd दोनों हैं जो बसे क्लास टाइप की है। तो, मैं pb पॉइंटर(pointer) में b का पता रखता हूं जो सामान्य है और मैं पीडी में d का एड्रेस रखता हूं जो B क्लास टाइप के पॉइंटर(pointer) जिसका मतलब है कि मैं एक upcast कर रहा हूं। एक a वस्तु है वास्तव में यहाँ पोइंटर(pointer) इस प्रकार का है। इसलिए, मैं यहां एक प्रतिनिधित्व कार्य कर रहा हूं। इसलिए, मैंने अपकास्ट(upcast) किया है। इसी तरह, एक ही बात मैंने संदर्भ के संदर्भ में लिखी है। यह rb का संदर्भ b ऑब्जेक्ट(object) का संदर्भ है, rd d ऑब्जेक्ट(object) का संदर्भ है, लेकिन केवल rd प्रकार B प्रकार का संदर्भ है। तो, यह आरडी कास्ट(cast) करेगा और डी के बारे में सोचता है जैसे कि यह बी प्रकार की वस्तु है। इसमें यह सेटिंग है और इसमें हम सभी प्रकार के फ़ंक्शन(function) कॉल करने का प्रयास कर रहे हैं। तो, हम दोनों वस्तुओं के लिए बुला रहे हैं b और d। हम दोनों कार्यों को कॉल करेंगे। तो, चार संयोजन और हम उन्हें तीन अलग-अलग तरीकों से कहेंगे। पहले हम ऑब्जेक्ट(object) का उपयोग करके फ़ंक्शन(function) को कॉल करते हैं। तो, b. f(),b. g (),d. f(),d. g()। हम जानते हैं कि किस फ़ंक्शन(function) को b .f ()कहा जाएगा; इस फ़ंक्शन(function) को b. g() कहा जाएगा, इस फ़ंक्शन(function) को b .d () कहा जाएगा, निश्चित रूप से इस फ़ंक्शन(function) को कॉल किया जाएगा। उस क्लास(class) के संबंधित कार्य को बुलाया जाएगा। तो, इसमें कोई आश्चर्य की बात नहीं है। अब, हम पॉइंटर(pointer) के माध्यम से उस फ़ंक्शन(function) कॉल को करने का प्रयास करते हैं। तो, pb b ऑब्जेक्ट(object) का पॉइंटर(pointer) है, p d ऑब्जेक्ट(object) का पॉइंटर(pointer) है, लेकिन ये दोनों B टाइप के हैं। इसलिए, चूंकि वे B प्रकार के हैं, इसलिए यदि मैं pb -> f() का आह्वान करता हूं, तो निश्चित रूप से मुझे उम्मीद है कि B क्लास(class) के कार्य को लागू किया जाएगा। तो, pb -> f ()को B:: f () इस फंक्शन को इनवाइट करना चाहिए। इसी तरह अगले pb -> g ()को g फ़ंक्शन(function) को इनवाइट करना चाहिए; pd -> f () pd भी बेस क्लास(class) का प्रकार है। तो, पीडी भी केवल इन दो कार्यों के बारे में जानता है। इसलिए, अगर मैं pd -> f () करता हूं, तो यह फिर से बी क्लास के f फंक्शन को आमंत्रित करता है। लेकिन जब आप पीडी -> जी () करते हैं तो पूरी तरह से आश्चर्य होता है। माइंड यू पीडी इस प्रकार का पोइंटर(pointer) है। यह वास्तव में इस प्रकार की एक वस्तु की ओर इशारा करता है। तो, पीडी का प्रकार यहां है। वह वस्तु वास्तव में यहां है, लेकिन जब मैं विधि का आह्वान करता हूं, तो यह किसी तरह यह पता लगाने में सक्षम होता है कि इसमें वास्तव में विज्ञापन वस्तु है और इस फ़ंक्शन(function) को लागू करने के बजाय यह वास्तव में इस फ़ंक्शन(function) को आमंत्रित करता है। और वह जो गतिशील(dynamic) बिंडिंग(binding) के रूप में जाना जाता है। तो, गतिशील(dynamic) बिंडिंग(binding) क्या है? बिंडिंग(binding) को आह्वान के संदर्भ में एक अभिव्यक्ति दी जाती है जो आप तय करते हैं कि किस फ़ंक्शन(function) को कहा जाएगा। इसलिए, हमने ओवरलोडिंग के संदर्भ में एक बिंडिंग(binding) बात भी की है कि यदि कई कार्य ओवरलोड हैं तो कौन सा कार्य बाध्य होगा। तो, यह एक समान अवधारणा है। तो, यह p पॉइंट(point)र pb -> f () या pd -> g () प्रश्न दिया गया है, जिसे हम उस विशेष फ़ंक्शन(function) से पूछना चाहते हैं जो इस कॉल के साथ बंधेगा। अब, हम जो देखते हैं वह फ़ंक्शन(function) f के मामले में है बिंडिंग(binding) स्थिर(static) है जिसका अर्थ है कि बिंडिंग(binding) द्वारा तय किया गया है मुझे फिर से इसे स्पष्ट करने दें। तो, यहाँ फ़ंक्शन(function) f के मामले में और यहाँ बिंडिंग(binding) स्थिर है जिसका अर्थ है कि यह किस फ़ंक्शन(function) को कॉल करता है, पोइंटर(pointer) के प्रकार पर निर्भर करता है। जिसका अर्थ है कि ऐसा कुछ जिसे स्टेटिक रूप से जाना जाता है, जिसे कंपाइल टाइम कंपाइलर(compiler) में हमेशा जाना जाता है, यह जानता है कि पॉइंटर(pointer) का प्रकार क्या है, लेकिन तथ्य यह है कि इस पॉइंटर(pointएर) में B ऑब्जेक्ट(object) की ओर इशारा करते हुए B ऑब्जेक्ट(object) है, जबकि यह पॉइंटर(pointer) D ऑब्जेक्ट(object) की ओर इशारा कर रहा है । स्थैतिक(static) बाइंडिंग(Binding) के मामले में, जो कि कोई विचार नहीं है, यह एक बी प्रकार पोइंटर(pointer) है, यह भी एक बी प्रकार पोइंटर(pointer) है। इसलिए, यदि मैं f को आमंत्रित करता हूं तो यह B::f () बेस क्लास की विधि है। यह बेस क्लास की एफ विधि को भी आमंत्रित करता है। दूसरे मामले में परिदृश्य में बदलाव, जहां हम कहते हैं कि हम गतिशील(dynamic) बांध रहे हैं यदि आप इन पर फिर से गौर करते हैं तो ये दोनों आधार प्रकार के संकेत हैं। और यह b ऑब्जेक्ट(object) को इंगित कर रहा है, यह विज्ञापन ऑब्जेक्ट(object) को इंगित कर रहा है। अब, हम पाते हैं कि जब यह पोइंटर(pointer) a b वस्तु की ओर इशारा कर रहा है, B:: g () यहीं है जो इस फ़ंक्शन(function) को आमंत्रित किया जा रहा है। जहां एक अलग समरूप अभिव्यक्ति के रूप में जहां पोइंटर(pointer) अभी भी B * प्रकार का है, लेकिन जब यह g () को आमंत्रित करता है तो यह दिया जाता है कि यह वास्तव में जिस वस्तु को इंगित कर रहा है वह विज्ञापन प्रकार वस्तु है D: g () जो कि यह ओवरराइड फ़ंक्शन(function) है व्युत्पन्न क्लास(class) में आह्वान किया जाता है। तो, यह पोइंटर(pointer) के प्रकार पर निर्भर नहीं करता है। इसलिए, कंपाइलर(compiler) के पास pb -> g () या pd -> g () के रूप में निर्णय लेने का कोई तरीका नहीं है, जो इसे कॉल करेगा क्योंकि यह पॉइंटर(pointer) के प्रकार से तय नहीं हो रहा है, लेकिन यह निर्णय ले रहा है वास्तव में रन टाइम पर। वस्तु का प्रकार क्या है या वह किस वस्तु की ओर इशारा करता है। तो, pd -> g और फ़ंक्शंस B: g () या D:: g (), इस बाइंडिंग(Binding) की अभिव्यक्ति के बीच की बाइंडिंग(Binding) यह यहाँ बाँधती है या यह यहाँ बांधती है, यह पॉइंटएर(pointer) पर निर्भर नहीं करता है। यह नुकीली वस्तु पर निर्भर करता है। यह pd पर निर्भर नहीं करता है यह इस बात पर निर्भर करता है कि नुकीली वस्तु का प्रकार क्या है। यदि इंगित की गई वस्तु का प्रकार b प्रकार का है क्योंकि यह यहाँ b प्रकार था, तो बेस क्लास का जी तरीका लागू किया जाता है। यदि यह d प्रकार का है, तो व्युत्पन्न क्लास(class) का जी तरीका लागू हो जाता है। और इसलिए, इसे गतिशील(dynamic) बिंडिंग(binding) कहा जाता है यह स्थिर बिंडिंग(binding) के विपरीत है। और क्या फर्क पड़ता है? फंक्शन से पहले इस महत्वपूर्ण शब्द से अंतर किया जाता है। तो, दो कार्यों के लिए यह एक आभासी(virtual) फ़ंक्शन(function) कहलाता है, जहाँ मैंने सामने की तरफ आभासी(virtual) लिखा है और इसे गैर-आभासी(virtual) फ़ंक्शन(function) कहा जाता है। और अगर मेरे पास एक गैर-आभासी(virtual) फ़ंक्शन(function) है जो कि हमारे पास पहले था। मेरे पास एक स्टैटिक बाइंडिंग(Binding) होगी और अगर मेरे पास एक वर्चुअल फंक्शन(virtual function) है तो मेरे पास एक डायनेमिक(dynamic) बाइंडिंग(Binding) होगी जहाँ अगर मैं उस फंक्शन को पॉइंटर(pointer) के माध्यम से कॉल करता हूँ तो यह पॉइंटर(pointer) के प्रकार पर निर्भर नहीं करेगा, बल्कि यह वास्तविक ऑब्जेक्ट(object) पर निर्भर करेगा वास्तविक वस्तु का प्रकार जो पोइंटर(pointer) रन टाइम पर इंगित करता है। इसलिए, यह निश्चित रूप से स्थैतिक(static) और गतिशील(dynamic) बिंडिंग(binding) के बीच एक बुनियादी अंतर है, मैं सिर्फ आपके लिए शब्दार्थ को प्रस्तुत करने की कोशिश कर रहा हूं। हमारे पास अभी भी हम यह समझने के लिए जाने के लिए एक छोटा सा तरीका है कि हम ऐसा क्यों कर रहे हैं। यह वास्तव में मॉडलिंग को लागू करने के मामले में कैसे मदद करेगा, लेकिन यह वर्चुअल फ़ंक्शन(function) और डायनामिक(Dynamic) बाइंडिंग(Binding) की यह मूल धारणा है जिसे हम यहां से समझना चाहते हैं। और अंतिम खंड में जहां हम संदर्भ का उपयोग करते हैं हम बिल्कुल उसी व्यवहार को देख सकते हैं। ये दो यहां हैं संदर्भ बी बी ऑब्जेक्ट(object) को संदर्भित करता है; rd का तात्पर्य d ऑब्जेक्ट(object) से है। फ़ंक्शन(function) f के लिए इसे फिर से अगर मैं इसे संदर्भ के माध्यम से करता हूं तो मेरे पास एक स्थिर बिंडिंग(binding) है, लेकिन निश्चित रूप से अगर मैं आरबी और आरडी के लिए जी फ़ंक्शन(function) जी विधि का आह्वान करता हूं क्योंकि आरडी d विज्ञापन वस्तु का उल्लेख कर रहा है और क्योंकि आरबी एक ब ऑब्जेक्ट(object) का उल्लेख कर रहा है। इस मामले में डायनेमिक बाइंडिंग(Binding) के अनुसार, मुझे प्राप्त व्युत्क्रम के g फंक्शन मिलेंगे। इस मामले में मुझे बेस क्लास के g फंक्शन को इनवाइट किया गया है। इसलिए, यदि मैं फ़ंक्शन(function) को ऑब्जेक्ट(object) के रूप में एक्सेस करता हूं तो वे हमेशा स्थिर रहेंगे। वे हमेशा उस वस्तु प्रकार पर आधारित होंगे। लेकिन अगर मैं फ़ंक्शन(function) के माध्यम से या संदर्भ के माध्यम से विधियों का आह्वान करता हूं तो मेरे पास स्थैतिक(static) या गतिशील(dynamic) बिंडिंग(binding) हो सकता है जो इस बात पर निर्भर करता है कि मैं जो सदस्य कार्य कर रहा हूं वह एक गैर-आभासी(virtual) है जहां स्थिर बिंडिंग(binding) होगा या जब सदस्य फ़ंक्शन(function) एक आभासी(virtual) होता है जहां गतिशील(dynamic) बिंडिंग(binding) होगा। तो, यह केवल बिंडिंग(binding) की मूल धारणा को पेश करना था इस पर आगे निर्माण होगा। इसलिए, योग करने के लिए हमने कास्टिंग(casting) की अवधारणा को पेश किया है और ऊपर उठने और उतरने की मूल धारणा पर चर्चा की है और देखा है कि अप कास्ट(cast) सुरक्षित है और डाउन कास्ट(cast) जोखिम भरा है। हमने ऐसा इसलिए किया है क्योंकि अगले मॉड्यूल(module) में, हमें बिंडिंग(binding) के संदर्भ में कास्टिंग(casting) की इस धारणा का उपयोग करने की आवश्यकता होगी। उसके बाद हमने स्थैतिक(static) कास्टिंग(casting) और डायनामिक(Dynamic) कास्टिंग(casting) या वर्चुअल फ़ंक्शन(function) की मूल परिभाषा को प्रस्तुत किया है जो एक नए प्रकार का सदस्य कार्य है जिसे हम आगे की कक्षाओं में पेश कर रहे हैं। हम अगले मॉड्यूल(module) में गतिशील(dynamic) बिंडिंग(binding) पर चर्चा जारी रखेंगे।