गतिशील प्रेषण: Difference between revisions

From Vigyanwiki
(Created page with "{{Short description|Selecting which implementation of a method or function to call at run time}} {{About|the selection of an implementation of a polymorphic operation |dynamic...")
 
No edit summary
 
(8 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{Short description|Selecting which implementation of a method or function to call at run time}}
[[कंप्यूटर विज्ञान]] में, गतिशील प्रेषण एक [[बहुरूपता (कंप्यूटर विज्ञान)]] संचालन ([[विधि (कंप्यूटर प्रोग्रामिंग)]] या फ़ंक्शन) के कार्यान्वयन को रन टाइम (प्रोग्राम जीवनचक्र चरण) पर कॉल करने की प्रक्रिया है। यह सामान्यतः [[ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग]] (OOP) भाषाओं और प्रणालियों में कार्यरत है, और इसकी एक प्रमुख विशेषता मानी जाती है।<ref name="Milton-Schmidt_1994" />
{{About|the selection of an implementation of a polymorphic operation |dynamic binding|Late binding}}
{{more footnotes|date=December 2010}}
{{use dmy dates|date=July 2022|cs1-dates=y}}
{{use list-defined references|date=July 2022}}
{{Polymorphism}}
[[कंप्यूटर विज्ञान]] में, डायनेमिक डिस्पैच एक [[बहुरूपता (कंप्यूटर विज्ञान)]] ऑपरेशन ([[विधि (कंप्यूटर प्रोग्रामिंग)]] या फ़ंक्शन) के कार्यान्वयन को रन टाइम (प्रोग्राम जीवनचक्र चरण) पर कॉल करने की प्रक्रिया है। यह आमतौर पर [[ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग]] (OOP) भाषाओं और प्रणालियों में कार्यरत है, और इसकी एक प्रमुख विशेषता मानी जाती है।<ref name="Milton-Schmidt_1994"/>


ऑब्जेक्ट-ओरिएंटेड सिस्टम एक समस्या को इंटरेक्टिंग ऑब्जेक्ट्स के एक सेट के रूप में मॉडल करते हैं जो नाम से संदर्भित संचालन को लागू करते हैं। बहुरूपता वह परिघटना है जिसमें कुछ विनिमेय वस्तुएं प्रत्येक एक ही नाम के एक ऑपरेशन को उजागर करती हैं लेकिन संभवतः व्यवहार में भिन्न होती हैं। एक उदाहरण के रूप में, ए {{mono|File}} वस्तु और ए {{mono|Database}} वस्तु दोनों में एक है {{mono|StoreRecord}} विधि जिसका उपयोग भंडारण के लिए कार्मिक रिकॉर्ड लिखने के लिए किया जा सकता है। उनके कार्यान्वयन भिन्न हैं। एक प्रोग्राम एक वस्तु के लिए एक संदर्भ रखता है जो या तो हो सकता है {{mono|File}} वस्तु या ए {{mono|Database}} वस्तु। यह कौन सा हो सकता है एक रन-टाइम सेटिंग द्वारा निर्धारित किया गया हो, और इस स्तर पर, प्रोग्राम को पता नहीं हो सकता है या परवाह नहीं है। जब प्रोग्राम कॉल करता है {{mono|StoreRecord}} वस्तु पर, कुछ को चुनने की जरूरत है कि कौन सा व्यवहार अधिनियमित हो। यदि कोई OOP को ऑब्जेक्ट को भेजे जाने वाले संदेश के रूप में सोचता है, तो इस उदाहरण में प्रोग्राम एक भेजता है {{mono|StoreRecord}} किसी अज्ञात प्रकार के ऑब्जेक्ट को संदेश, संदेश को सही ऑब्जेक्ट पर भेजने के लिए इसे रन-टाइम सपोर्ट सिस्टम पर छोड़ देता है। वस्तु जो भी व्यवहार लागू करती है उसे लागू करती है।<ref name="Driesen-Hoelzle-Vitek_1995"/>
ऑब्जेक्ट-ओरिएंटेड सिस्टम एक समस्या को अंतःक्रिया ऑब्जेक्ट्स के एक सेट के रूप में मॉडल करते हैं जो नाम से संदर्भित संचालन को लागू करते हैं। बहुरूपता वह परिघटना है जिसमें कुछ विनिमेय वस्तुएं प्रत्येक एक ही नाम के एक संचालन को उजागर करती हैं लेकिन संभवतः व्यवहार में भिन्न होती हैं। एक उदाहरण के रूप में, ए {{mono|फाइल}} वस्तु और ए {{mono|डेटाबेस}} वस्तु दोनों में एक है {{mono|स्टोर रिकॉर्ड}} विधि जिसका उपयोग भंडारण के लिए कार्मिक रिकॉर्ड लिखने के लिए किया जा सकता है। उनके कार्यान्वयन भिन्न हैं। एक प्रोग्राम एक वस्तु के लिए एक संदर्भ रखता है जो या तो एक फाइल हो सकता है {{mono|फाइल}} वस्तु या ए {{mono|डेटाबेस}} वस्तु यह कुछ भी हो सकता है, एक रन-टाइम सेटिंग द्वारा निर्धारित किया गया हो, और इस स्तर पर, प्रोग्राम को पता नहीं हो सकता है या परवाह नहीं है। जब प्रोग्राम कॉल करता है तो {{mono|स्टोर रिकॉर्ड}} वस्तु पर, कुछ को चुनने की जरूरत है कि कौन सा व्यवहार अधिनियमित हो। यदि कोई OOP को ऑब्जेक्ट को भेजे जाने वाले संदेश के रूप में सोचता है, तो इस उदाहरण में प्रोग्राम एक भेजता है, {{mono|स्टोर रिकॉर्ड}} किसी अज्ञात प्रकार के ऑब्जेक्ट को संदेश को सही ऑब्जेक्ट पर भेजने के लिए इसे रन-टाइम सपोर्ट सिस्टम पर छोड़ देता है। वस्तु जो भी व्यवहार लागू करती है।<ref name="Driesen-Hoelzle-Vitek_1995" />


डायनेमिक डिस्पैच [[स्थिर प्रेषण]] के विपरीत है, जिसमें एक पॉलीमॉर्फिक ऑपरेशन के कार्यान्वयन को [[संकलन समय]] पर चुना जाता है। डायनेमिक डिस्पैच का उद्देश्य एक उपयुक्त कार्यान्वयन के चयन को तब तक टालना है जब तक कि रन टाइम प्रकार का पैरामीटर (या एकाधिक पैरामीटर) ज्ञात न हो जाए।
गतिशील प्रेषण [[स्थिर प्रेषण]] के विपरीत है, जिसमें एक बहुरूपी संचालन के कार्यान्वयन को [[संकलन समय]] पर चुना जाता है। गतिशील प्रेषण का उद्देश्य एक उपयुक्त कार्यान्वयन के चयन को तब तक टाला जाता है जब तक कि रन टाइम प्रकार का पैरामीटर (या एकाधिक पैरामीटर) ज्ञात न हो जाए। गतिशील विधि प्रेषण एक ऐसा तरीका है, जो प्रोग्राम के रनटाइम में ये तय करता है कि किसी ऑब्जेक्ट के रेफ़्रेन्स में कौनसा मेथड एक्सेक्यूटे होगा ना कि कम्पाइल टाइम में गतिशील विधि प्रेषण इसीलिए महत्वपूर्ण है क्योंकि यही वह तरीका है जिससे जावा रन टाइम बहुरूपता को कार्यान्वित करता है।


डायनेमिक डिस्पैच [[देर से बाँधना]] (डायनेमिक बाइंडिंग के रूप में भी जाना जाता है) से अलग है। [[नाम बंधन]] एक नाम को एक ऑपरेशन के साथ जोड़ता है। एक बहुरूपी ऑपरेशन में कई कार्यान्वयन होते हैं, जो सभी एक ही नाम से जुड़े होते हैं। बाइंडिंग को संकलित समय पर या (देर से बाइंडिंग के साथ) रन टाइम पर बनाया जा सकता है। डायनेमिक डिस्पैच के साथ, ऑपरेशन के एक विशेष कार्यान्वयन को रन टाइम पर चुना जाता है। जबकि डायनेमिक डिस्पैच में लेट बाइंडिंग नहीं होती है, लेट बाइंडिंग डायनेमिक डिस्पैच का संकेत देती है, क्योंकि लेट-बाउंड ऑपरेशन के कार्यान्वयन को रन टाइम तक नहीं जाना जाता है।{{fact|reason=This paragraph is confused and conflicts with most definitions|date=October 2018}}
गतिशील प्रेषण [[देर से बाँधना|लेट बाइंडिंग]] (गतिशील बाइंडिंग के रूप में भी जाना जाता है) से अलग है। [[नाम बंधन|नाम बाइंडिंग]] एक नाम को एक संचालन के साथ जोड़ता है। एक बहुरूपी संचालन में कई कार्यान्वयन होते हैं, जो सभी एक ही नाम से जुड़े होते हैं। बाइंडिंग को संकलित समय पर या (देर से बाइंडिंग के साथ) रन टाइम पर बनाया जा सकता है। गतिशील प्रेषण के साथ, संचालन के एक विशेष कार्यान्वयन को रन टाइम पर चुना जाता है। जबकि गतिशील प्रेषण में लेट बाइंडिंग नहीं होती है, लेट बाइंडिंग गतिशील प्रेषण का संकेत देती है, क्योंकि लेट-बाउंड संचालन के कार्यान्वयन को रन टाइम तक नहीं जाना जाता है।{{fact|reason=This paragraph is confused and conflicts with most definitions|date=October 2018}}




== सिंगल और मल्टीपल डिस्पैच ==
==सिंगल और मल्टीपल प्रेषण ==
{{Main|Multiple dispatch}}
{{Main|एकाधिक प्रेषण}}
कॉल करने की विधि के किस संस्करण का विकल्प या तो एक वस्तु पर या वस्तुओं के संयोजन पर आधारित हो सकता है। पहले वाले को सिंगल डिस्पैच कहा जाता है और यह सामान्य ऑब्जेक्ट-ओरिएंटेड भाषाओं जैसे स्मॉलटाक, [[सी ++]], [[जावा (प्रोग्रामिंग भाषा)]], सी शार्प (प्रोग्रामिंग लैंग्वेज)|सी#, [[उद्देश्य सी]], [[स्विफ्ट (प्रोग्रामिंग भाषा)]], [[जावास्क्रिप्ट]] और सीधे समर्थित है। [[पायथन (प्रोग्रामिंग भाषा)]]। इन और इसी तरह की भाषाओं में, एक समान सिंटैक्स के साथ डिवीजन (गणित) के लिए एक विधि कह सकते हैं
<वाक्यविन्यास लैंग = अजगर>
डिविडेंड.डिवाइड (भाजक) # लाभांश / भाजक
</वाक्यविन्यास हाइलाइट>
जहां पैरामीटर वैकल्पिक हैं। इसे नाम का संदेश भेजने के रूप में माना जाता है {{mono|divide}} पैरामीटर के साथ {{mono|divisor}} को {{mono|dividend}}. कार्यान्वयन के आधार पर ही चयन किया जाएगा {{mono|dividend}}का प्रकार (शायद परिमेय संख्याएँ, [[तैरनेवाला स्थल]], [[मैट्रिक्स (गणित)]]), के प्रकार या मूल्य की अवहेलना {{mono|divisor}}.


इसके विपरीत, कुछ भाषाएँ ऑपरेंड के संयोजन के आधार पर विधियों या कार्यों को प्रेषित करती हैं; विभाजन मामले में, के प्रकार {{mono|dividend}} और {{mono|divisor}} एक साथ निर्धारित करें कि कौन सा {{mono|divide}} ऑपरेशन किया जाएगा। इसे एकाधिक प्रेषण के रूप में जाना जाता है। एकाधिक प्रेषण का समर्थन करने वाली भाषाओं के उदाहरण [[सामान्य लिस्प]], [[डायलन (प्रोग्रामिंग भाषा)]] और [[जूलिया (प्रोग्रामिंग भाषा)]] हैं।
कॉल करने की विधि के किसी संस्करण का विकल्प या तो एक वस्तु पर या वस्तुओं के संयोजन पर आधारित हो सकता है। पहले वाले को सिंगल प्रेषण कहा जाता है और यह सामान्य ऑब्जेक्ट-ओरिएंटेड भाषाओं जैसे स्मॉलटाक, [[सी ++|C++]], [[जावा (प्रोग्रामिंग भाषा)]], सी शार्प (प्रोग्रामिंग लैंग्वेज), सी#, [[उद्देश्य सी|ऑब्जेक्टिव सी]], [[स्विफ्ट (प्रोग्रामिंग भाषा)]], [[जावास्क्रिप्ट]] और सीधे समर्थित है। [[पायथन (प्रोग्रामिंग भाषा)]] इन और इसी तरह की भाषाओं में, एक समान सिंटैक्स के साथ डिवीजन (गणित) के लिए एक विधि कह सकते हैं


== गतिशील प्रेषण तंत्र ==
<syntaxhighlight lang="python">
विभिन्न गतिशील प्रेषण तंत्रों के साथ एक भाषा लागू की जा सकती है। किसी भाषा द्वारा प्रदान किए गए गतिशील प्रेषण तंत्र के विकल्प काफी हद तक उन प्रोग्रामिंग प्रतिमानों को बदल देते हैं जो किसी भाषा में उपलब्ध हैं या उपयोग करने के लिए सबसे स्वाभाविक हैं।
dividend.divide(divisor)  # dividend / divisor
</syntaxhighlight>


आम तौर पर, एक टाइप की गई भाषा में, प्रेषण तंत्र तर्कों के प्रकार के आधार पर किया जाएगा (आमतौर पर संदेश के रिसीवर के प्रकार के आधार पर)। कमजोर या कोई टाइपिंग सिस्टम वाली भाषाएं अक्सर प्रत्येक वस्तु के लिए वस्तु डेटा के भाग के रूप में एक प्रेषण तालिका ले जाती हैं। यह इंस्टेंस व्यवहार की अनुमति देता है क्योंकि प्रत्येक इंस्टेंस किसी दिए गए संदेश को एक अलग विधि में मैप कर सकता है।
जहां पैरामीटर वैकल्पिक हैं। इसे डिविडेंड के लिए पैरामीटर डिवाइडर के साथ डिवाइड नामक संदेश भेजने के रूप में माना जाता है। विभाजक के प्रकार या मूल्य की उपेक्षा करते हुए केवल लाभांश के प्रकार (शायद तर्कसंगत, [[फ्लोटिंग पॉइंट]], [[मैट्रिक्स (गणित)|मैट्रिक्स]]) के आधार पर एक कार्यान्वयन चुना जाएगा।
 
इसके विपरीत, कुछ भाषाएँ ऑपरेंड के संयोजन के आधार पर विधियों या कार्यों को प्रेषित करती हैं; विभाजन प्रकरण में, लाभांश और भाजक के प्रकार एक साथ निर्धारित करते हैं कि कौन सा विभाजन संचालन किया जाएगा। इसे एकाधिक प्रेषण के रूप में जाना जाता है। एकाधिक प्रेषण का समर्थन करने वाली भाषाओं के उदाहरण [[कॉमन लिस्प]], [[डायलन]] और [[जूलिया सेट|जूलिया]] हैं।
 
==गतिशील प्रेषण तंत्र ==
विभिन्न गतिशील प्रेषण तंत्रों के साथ एक भाषा लागू की जा सकती है। किसी भाषा द्वारा प्रदान किए गए गतिशील प्रेषण तंत्र के विकल्प काफी सीमा तक उन प्रोग्रामिंग प्रतिमानों को बदल देते हैं जो किसी भाषा में उपलब्ध हैं या उपयोग करने के लिए सबसे स्वाभाविक हैं।
 
सामान्यतः, एक टाइप की गई भाषा में, प्रेषण तंत्र तर्कों के प्रकार के आधार पर किया जाएगा (सामान्यतः संदेश के प्राप्तकर्ता के प्रकार के आधार पर)। कमजोर या कोई टाइपिंग सिस्टम वाली भाषाएं प्रायः प्रत्येक वस्तु के लिए वस्तु डेटा के भाग के रूप में एक प्रेषण तालिका ले जाती हैं। यह त्वरित व्यवहार की अनुमति देता है क्योंकि प्रत्येक त्वरित किसी दिए गए संदेश को एक अलग विधि में मैप कर सकता है।


कुछ भाषाएँ हाइब्रिड दृष्टिकोण प्रदान करती हैं।
कुछ भाषाएँ हाइब्रिड दृष्टिकोण प्रदान करती हैं।


डायनेमिक डिस्पैच में हमेशा एक ओवरहेड होता है इसलिए कुछ भाषाएँ विशेष तरीकों के लिए स्टैटिक डिस्पैच की पेशकश करती हैं।
गतिशील प्रेषण में सदैव एक ओवरहेड होता है इसलिए कुछ भाषाएँ विशेष तरीकों के लिए स्थैतिक प्रेषण की पेशकश करती हैं।


=== सी ++ कार्यान्वयन ===
===C++ कार्यान्वयन===
C++ अर्ली बाइंडिंग का उपयोग करता है और डायनेमिक और स्टैटिक डिस्पैच दोनों प्रदान करता है। प्रेषण का डिफ़ॉल्ट रूप स्थिर है। गतिशील प्रेषण प्राप्त करने के लिए प्रोग्रामर को एक विधि घोषित करनी चाहिए {{mono|virtual}}.
C++ बाइंडिंग का उपयोग करता है और गतिशील और स्थैतिक प्रेषण दोनों प्रदान करता है। प्रेषण का सामान्य रूप स्थिर है। गतिशील प्रेषण प्राप्त करने के लिए प्रोग्रामर को एक वर्चुअल विधि घोषित करनी चाहिए।


सी ++ कंपाइलर्स आमतौर पर वर्चुअल विधि तालिका (vtable) नामक डेटा संरचना के साथ गतिशील प्रेषण को कार्यान्वित करते हैं जो किसी दिए गए वर्ग के लिए सदस्य फ़ंक्शन पॉइंटर्स के सेट के रूप में नाम-से-कार्यान्वयन मैपिंग को परिभाषित करता है। (यह विशुद्ध रूप से एक कार्यान्वयन विवरण है; C ++ विनिर्देश vtables का उल्लेख नहीं करता है।) उस प्रकार के उदाहरण तब इस तालिका में उनके उदाहरण डेटा के भाग के रूप में एक सूचक को संग्रहीत करेंगे। यह जटिल है जब [[एकाधिक वंशानुक्रम]] का उपयोग किया जाता है। चूंकि सी ++ देर से बाध्यकारी का समर्थन नहीं करता है, सी ++ ऑब्जेक्ट में वर्चुअल टेबल को रन-टाइम पर संशोधित नहीं किया जा सकता है, जो प्रेषण लक्ष्य के संभावित सेट को संकलन समय पर चुने गए सीमित सेट तक सीमित करता है।
C++ कंपाइलर्स सामान्यतः वर्चुअल विधि तालिका (वी टेबल) नामक डेटा संरचना के साथ गतिशील प्रेषण को कार्यान्वित करते हैं जो किसी दिए गए वर्ग के लिए सदस्य फ़ंक्शन पॉइंटर्स के सेट के रूप में नाम-से-कार्यान्वयन मैपिंग को परिभाषित करता है। (यह विशुद्ध रूप से एक कार्यान्वयन विवरण है; C ++ विनिर्देश वी टेबलs का उल्लेख नहीं करता है।) उस प्रकार के उदाहरण तब इस तालिका में उनके उदाहरण डेटा के भाग के रूप में एक सूचक को संग्रहीत करेंगे। यह जटिल है जब [[एकाधिक वंशानुक्रम]] का उपयोग किया जाता है। चूंकि C++ देर से बाध्यकारी का समर्थन नहीं करता है, C++ ऑब्जेक्ट में वर्चुअल टेबल को रन-टाइम पर संशोधित नहीं किया जा सकता है, जो प्रेषण लक्ष्य के संभावित सेट को संकलन समय पर चुने गए सीमित सेट तक सीमित करता है।


टाइप ओवरलोडिंग सी ++ में गतिशील प्रेषण का उत्पादन नहीं करता है क्योंकि भाषा संदेश पैरामीटर के प्रकारों को औपचारिक संदेश नाम का हिस्सा मानती है। इसका मतलब यह है कि प्रोग्रामर जो संदेश नाम देखता है वह बाइंडिंग के लिए इस्तेमाल किया जाने वाला औपचारिक नाम नहीं है।
टाइप ओवरलोडिंग C++ में गतिशील प्रेषण का उत्पादन नहीं करता है क्योंकि भाषा संदेश पैरामीटर के प्रकारों को औपचारिक संदेश नाम का हिस्सा मानती है। इसका मतलब यह है कि प्रोग्रामर जो संदेश नाम देखता है वह बाइंडिंग के लिए उपयोग किया जाने वाला औपचारिक नाम नहीं है।


=== जाओ और जंग कार्यान्वयन ===
===Go और Rust कार्यान्वयन===
[[जाओ (प्रोग्रामिंग भाषा)]], [[जंग (प्रोग्रामिंग भाषा)]] और [[निम (प्रोग्रामिंग भाषा)]] में, शुरुआती बाइंडिंग के अधिक बहुमुखी रूपांतर का उपयोग किया जाता है।
[[जाओ (प्रोग्रामिंग भाषा)|Go (प्रोग्रामिंग भाषा)]], [[जंग (प्रोग्रामिंग भाषा)|Rust (प्रोग्रामिंग भाषा)]] और [[निम (प्रोग्रामिंग भाषा)]] में, प्रारम्भिक बाइंडिंग के अधिक बहुमुखी रूपांतर का उपयोग किया जाता है।
  {{anchor|Fat pointer}}Vtable पॉइंटर्स को ऑब्जेक्ट रेफरेंस के साथ 'फैट पॉइंटर्स' (गो में 'इंटरफेस', या रस्ट में 'ट्रेट ऑब्जेक्ट्स') के रूप में ले जाया जाता है।{{cn|date=July 2022}}
  {{anchor|Fat pointer}}वी टेबल पॉइंटर्स को ऑब्जेक्ट रेफरेंस के साथ 'फैट पॉइंटर्स' (गो में 'अंतरापृष्ठ', या रस्ट में 'ट्रेट ऑब्जेक्ट्स') के रूप में ले जाया जाता है।{{cn|date=July 2022}}
यह अंतर्निहित डेटा संरचनाओं से समर्थित इंटरफेस को अलग करता है। प्रत्येक संकलित लाइब्रेरी को किसी प्रकार का सही ढंग से उपयोग करने के लिए समर्थित इंटरफेस की पूरी श्रृंखला को जानने की आवश्यकता नहीं है, केवल विशिष्ट व्यवहार्य लेआउट जिसकी उन्हें आवश्यकता होती है। कोड अलग-अलग इंटरफेस को अलग-अलग कार्यों के लिए डेटा के एक ही टुकड़े में पास कर सकता है। यह बहुमुखी प्रतिभा प्रत्येक वस्तु संदर्भ के साथ अतिरिक्त डेटा की कीमत पर आती है, जो कि समस्याग्रस्त है यदि ऐसे कई संदर्भों को लगातार संग्रहीत किया जाता है।
यह अंतर्निहित डेटा संरचनाओं से समर्थित अंतरापृष्ठ को अलग करता है। प्रत्येक संकलित लाइब्रेरी को किसी प्रकार का सही ढंग से उपयोग करने के लिए समर्थित अंतरापृष्ठ की पूरी श्रृंखला को जानने की आवश्यकता नहीं है, केवल विशिष्ट व्यवहार्य लेआउट जिसकी उन्हें आवश्यकता होती है। कोड अलग-अलग अंतरापृष्ठ को अलग-अलग कार्यों के लिए डेटा के एक ही टुकड़े में पास कर सकता है। यह बहुमुखी प्रतिभा प्रत्येक वस्तु संदर्भ के साथ अतिरिक्त डेटा की कीमत पर आती है, जो कि समस्याग्रस्त है यदि ऐसे कई संदर्भों को लगातार संग्रहीत किया जाता है।फैट पॉइंटर शब्द केवल अतिरिक्त संबंधित जानकारी के साथ एक पॉइंटर (कंप्यूटर प्रोग्रामिंग) को संदर्भित करता है। अतिरिक्त जानकारी ऊपर वर्णित गतिशील प्रेषण के लिए एक व्यवहार्य सूचक हो सकती है, लेकिन अधिक सामान्य रूप से संबंधित वस्तु का आकार वर्णन करने के लिए एक टुकड़ा है।{{cn|date=जुलाई 2022}} {{See also|स्मार्ट सूचक}}


फैट पॉइंटर शब्द केवल अतिरिक्त संबंधित जानकारी के साथ एक पॉइंटर (कंप्यूटर प्रोग्रामिंग) को संदर्भित करता है। अतिरिक्त जानकारी ऊपर वर्णित गतिशील प्रेषण के लिए एक व्यवहार्य सूचक हो सकती है, लेकिन अधिक सामान्य रूप से संबंधित वस्तु का आकार वर्णन करने के लिए है। एक टुकड़ा।{{cn|date=July 2022}} {{See also|Smart pointer}}


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


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


क्योंकि एक प्रकार में आधार प्रकार की श्रृंखला हो सकती है, यह लुक-अप महंगा हो सकता है। स्मॉलटाक के तंत्र का एक सरल कार्यान्वयन सी ++ की तुलना में काफी अधिक ओवरहेड प्रतीत होता है और यह ओवरहेड प्रत्येक ऑब्जेक्ट को प्राप्त होने वाले प्रत्येक संदेश के लिए खर्च किया जाएगा।
रियल स्मॉलटाक कार्यान्वयन प्रायः [[इनलाइन कैशिंग]] नामक तकनीक का उपयोग करते हैं<ref name="Mueller_1995" />यह विधि प्रेषण को बहुत तेज़ बनाता है। इनलाइन कैशिंग मूल रूप से कॉल साइट के पिछले डेस्टिनेशन मेथड एड्रेस और ऑब्जेक्ट क्लास (या मल्टी-वे कैशिंग के लिए कई जोड़े) को स्टोर करता है। विधि चयनकर्ता के आधार पर कैश्ड विधि को सबसे आम लक्ष्य विधि (या केवल कैश मिस हैंडलर) के साथ प्रारंभ किया गया है। जब विधि कॉल साइट निष्पादन के दौरान पहुंच जाती है, तो यह केवल कैश में पते को कॉल करती है। (गतिशील कोड जनरेटर में, यह कॉल एक डायरेक्ट कॉल है क्योंकि डायरेक्ट एड्रेस कैश मिस लॉजिक द्वारा वापस पैच किया जाता है।) कॉल किए गए तरीके में प्रोलॉग कोड फिर कैश्ड क्लास की तुलना वास्तविक ऑब्जेक्ट क्लास से करता है, और यदि वे मेल नहीं खाते हैं , कक्षा में सही विधि खोजने के लिए एक कैश मिस हैंडलर को निष्पादन शाखाएँ। एक तेज़ कार्यान्वयन में कई कैश प्रविष्टियाँ हो सकती हैं और प्रारंभिक कैश मिस पर सही तरीके से निष्पादन प्राप्त करने के लिए प्रायः केवल कुछ निर्देशों की आवश्यकता होती है। सामान्य मामला एक कैश्ड क्लास मैच होगा, और विधि में निष्पादन जारी रहेगा।
 
रियल स्मॉलटाक कार्यान्वयन अक्सर [[इनलाइन कैशिंग]] नामक तकनीक का उपयोग करते हैं<ref name="Mueller_1995"/>यह विधि प्रेषण को बहुत तेज़ बनाता है। इनलाइन कैशिंग मूल रूप से कॉल साइट के पिछले डेस्टिनेशन मेथड एड्रेस और ऑब्जेक्ट क्लास (या मल्टी-वे कैशिंग के लिए कई जोड़े) को स्टोर करता है। विधि चयनकर्ता के आधार पर कैश्ड विधि को सबसे आम लक्ष्य विधि (या केवल कैश मिस हैंडलर) के साथ प्रारंभ किया गया है। जब विधि कॉल साइट निष्पादन के दौरान पहुंच जाती है, तो यह केवल कैश में पते को कॉल करती है। (डायनेमिक कोड जनरेटर में, यह कॉल एक डायरेक्ट कॉल है क्योंकि डायरेक्ट एड्रेस कैश मिस लॉजिक द्वारा वापस पैच किया जाता है।) कॉल किए गए तरीके में प्रोलॉग कोड फिर कैश्ड क्लास की तुलना वास्तविक ऑब्जेक्ट क्लास से करता है, और यदि वे मेल नहीं खाते हैं , कक्षा में सही विधि खोजने के लिए एक कैश मिस हैंडलर को निष्पादन शाखाएँ। एक तेज़ कार्यान्वयन में कई कैश प्रविष्टियाँ हो सकती हैं और प्रारंभिक कैश मिस पर सही तरीके से निष्पादन प्राप्त करने के लिए अक्सर केवल कुछ निर्देशों की आवश्यकता होती है। सामान्य मामला एक कैश्ड क्लास मैच होगा, और विधि में निष्पादन जारी रहेगा।


ऑब्जेक्ट क्लास और मेथड सेलेक्टर का उपयोग करके आउट-ऑफ-लाइन कैशिंग का उपयोग मेथड इनवोकेशन लॉजिक में भी किया जा सकता है। एक डिज़ाइन में, वर्ग और विधि चयनकर्ता को हैश किया जाता है, और एक विधि प्रेषण कैश तालिका में एक अनुक्रमणिका के रूप में उपयोग किया जाता है।
ऑब्जेक्ट क्लास और मेथड सेलेक्टर का उपयोग करके आउट-ऑफ-लाइन कैशिंग का उपयोग मेथड इनवोकेशन लॉजिक में भी किया जा सकता है। एक डिज़ाइन में, वर्ग और विधि चयनकर्ता को हैश किया जाता है, और एक विधि प्रेषण कैश तालिका में एक अनुक्रमणिका के रूप में उपयोग किया जाता है।
Line 61: Line 56:
पाइथन (प्रोग्रामिंग लैंग्वेज), [[रूबी (प्रोग्रामिंग भाषा)]], ऑब्जेक्टिव-सी और [[ग्रूवी (प्रोग्रामिंग भाषा)]] सहित कई अन्य गतिशील रूप से टाइप की गई भाषाएँ समान दृष्टिकोण का उपयोग करती हैं।
पाइथन (प्रोग्रामिंग लैंग्वेज), [[रूबी (प्रोग्रामिंग भाषा)]], ऑब्जेक्टिव-सी और [[ग्रूवी (प्रोग्रामिंग भाषा)]] सहित कई अन्य गतिशील रूप से टाइप की गई भाषाएँ समान दृष्टिकोण का उपयोग करती हैं।


== पायथन == में उदाहरण
<वाक्यविन्यास लैंग = अजगर>
वर्ग बिल्ली:
    डेफ बोलो (स्वयं):
        प्रिंट (म्याऊ)


वर्ग कुत्ता:
'''<big>पायथन में उदाहरण</big>'''
     डेफ बोलो (स्वयं):
<syntaxhighlight lang="python">
         प्रिंट (वूफ़)
class Cat:
     def speak(self):
         print("Meow")


class Dog:
    def speak(self):
        print("Woof")


डेफ बोलो (पीईटी):
    # डायनेमिकली स्पीक मेथड डिस्पैच करता है
    # पालतू या तो बिल्ली या कुत्ते का उदाहरण हो सकता है
    पालतू बोलो ()


बिल्ली = बिल्ली ()
def speak(pet):
बोलो (बिल्ली)
    # Dynamically dispatches the speak method
कुत्ता = कुत्ता ()
    # pet can either be an instance of Cat or Dog
बोलो (कुत्ते)
    pet.speak()
</वाक्यविन्यास हाइलाइट>


== सी ++ == में उदाहरण
cat = Cat()
<वाक्यविन्यास लैंग = सीपीपी>
speak(cat)
#शामिल <iostream>
dog = Dog()
speak(dog)
</syntaxhighlight>


// पेट को एब्स्ट्रैक्ट वर्चुअल बेस क्लास बनाएं
<big>'''C++ में उदाहरण'''</big>
कक्षा पालतू {
<syntaxhighlight lang="cpp">
जनता:
#include <iostream>
     आभासी शून्य बोलो () = 0;
 
// make Pet an abstract virtual base class
class Pet {
public:
     virtual void speak() = 0;
};
};


क्लास डॉग : पब्लिक पेट {
class Dog : public Pet {
जनता:
public:
     शून्य बोलें () ओवरराइड
     void speak() override
     {
     {
         एसटीडी :: अदालत << वाह!\n;
         std::cout << "Woof!\n";
     }
     }
};
};


क्लास कैट : पब्लिक पेट {
class Cat : public Pet {
जनता:
public:
     शून्य बोलें () ओवरराइड
     void speak() override
     {
     {
         एसटीडी :: अदालत << म्याऊ!\n;
         std::cout << "Meow!\n";
     }
     }
};
};


// बोलें () पेट से प्राप्त कुछ भी स्वीकार करने में सक्षम होगा
// speak() will be able to accept anything deriving from Pet
शून्य बोल (पालतू और पालतू)
void speak(Pet& pet)
{
{
     पालतू बोलो ();
     pet.speak();
}
}


मुख्य प्रवेश बिंदु()
int main()
{
{
     डॉग फिडो;
     Dog fido;
     बिल्ली सिम्बा;
     Cat simba;
     बोलो (फ़िदो);
     speak(fido);
     बोलो (सिम्बा);
     speak(simba);
     वापसी 0;
     return 0;
}
}
</वाक्यविन्यास हाइलाइट>
</syntaxhighlight>


== यह भी देखें ==
==यह भी देखें==
* [[समारोह बहु-संस्करण]]
*[[समारोह बहु-संस्करण]]
* [[फंक्शन ओवरलोडिंग]]
*[[फंक्शन ओवरलोडिंग]]
* संदेश देना
*संदेश देना
* [[ओवरराइडिंग विधि]]
*[[ओवरराइडिंग विधि]]
* [[दोहरा प्रेषण]]
*[[दोहरा प्रेषण]]
* नाम बंधन
*नाम बाइंडिंग


==संदर्भ==
==संदर्भ==
Line 142: Line 138:


==अग्रिम पठन==
==अग्रिम पठन==
* {{cite book |title=Inside the C++ Object Model |author-first=Stanley B. |author-last=Lippman |author-link=Stanley B. Lippman |date=1996 |publisher=[[Addison-Wesley]] |isbn=0-201-83454-5}}
*{{cite book |title=Inside the C++ Object Model |author-first=Stanley B. |author-last=Lippman |author-link=Stanley B. Lippman |date=1996 |publisher=[[Addison-Wesley]] |isbn=0-201-83454-5}}
* {{cite newsgroup |title=GEOS/NDO info for RBIL62? |author-first1=Marcus |author-last1=Groeber |author-first2=Edward "Ed" |author-last2=Di Geronimo, Jr. |author-first3=Matthias R. |author-last3=Paul |date=2002-03-02 |orig-date=2002-02-24 |newsgroup=comp.os.geos.programmer |url=https://groups.google.com/d/msg/comp.os.geos.programmer/8NNPJ4VU23A/cucVV95kf9oJ |access-date=2019-04-20 |url-status=live |archive-url=https://archive.today/20190420111421/https://groups.google.com/forum/%23!msg/comp.os.geos.programmer/8NNPJ4VU23A/cucVV95kf9oJ |archive-date=2019-04-20 |quote=[…] The reason [[PC/GEOS|Geos]] needs 16 interrupts is because the scheme is used to convert inter-segment ("far") function calls into interrupts, without changing the size of the code. The reason this is done so that "something" (the kernel) can hook itself into every inter-segment call made by a Geos application and make sure that the proper code segments are loaded from [[virtual memory]] and locked down. In [[DOS]] terms, this would be comparable to an [[overlay (programming)|overlay]] loader, but one that can be added without requiring explicit support from the compiler or the application. What happens is something like this: […] 1. The real mode compiler generates an instruction like this: CALL [[segment:offset addressing (x86)|<segment>:<offset>]] -> 9A <offlow><offhigh><seglow><seghigh> with <seglow><seghigh> normally being defined as an address that must be fixed up at load time depending on the address where the code has been placed. […] 2. The Geos linker turns this into something else: INT 8xh -> CD 8x […] DB <seghigh>,<offlow>,<offhigh> […] Note that this is again five bytes, so it can be fixed up "in place". Now the problem is that an interrupt requires two bytes, while a CALL FAR instruction only needs one. As a result, the 32-bit vector (<seg><ofs>) must be compressed into 24 bits. […] This is achieved by two things: First, the <seg> address is encoded as a "handle" to the segment, whose lowest [[nibble]] is always zero. This saves four bits. In addition […] the remaining four bits go into the low nibble of the interrupt vector, thus creating anything from INT 80h to 8Fh. […] The interrupt handler for all those vectors is the same. It will "unpack" the address from the three-and-a-half byte notation, look up the absolute address of the segment, and forward the call, after having done its virtual memory loading thing... Return from the call will also pass through the corresponding unlocking code. […] The low nibble of the interrupt vector (80h–8Fh) holds bit 4 through 7 of the segment handle. Bit 0 to 3 of a segment handle are (by definition of a Geos handle) always 0. […] all Geos API run through the "overlay" scheme […]: when a Geos application is loaded into memory, the loader will automatically replace calls to functions in the system libraries by the corresponding INT-based calls. Anyway, these are not constant, but depend on the handle assigned to the library's code segment. […] Geos was originally intended to be converted to [[protected mode]] very early on […], with [[real mode]] only being a "legacy option" […] almost every single line of assembly code is ready for it […]}}
*{{cite newsgroup |title=GEOS/NDO info for RBIL62? |author-first1=Marcus |author-last1=Groeber |author-first2=Edward "Ed" |author-last2=Di Geronimo, Jr. |author-first3=Matthias R. |author-last3=Paul |date=2002-03-02 |orig-date=2002-02-24 |newsgroup=comp.os.geos.programmer |url=https://groups.google.com/d/msg/comp.os.geos.programmer/8NNPJ4VU23A/cucVV95kf9oJ |access-date=2019-04-20 |url-status=live |archive-url=https://archive.today/20190420111421/https://groups.google.com/forum/%23!msg/comp.os.geos.programmer/8NNPJ4VU23A/cucVV95kf9oJ |archive-date=2019-04-20 |quote=[…] The reason [[PC/GEOS|Geos]] needs 16 interrupts is because the scheme is used to convert inter-segment ("far") function calls into interrupts, without changing the size of the code. The reason this is done so that "something" (the kernel) can hook itself into every inter-segment call made by a Geos application and make sure that the proper code segments are loaded from [[virtual memory]] and locked down. In [[DOS]] terms, this would be comparable to an [[overlay (programming)|overlay]] loader, but one that can be added without requiring explicit support from the compiler or the application. What happens is something like this: […] 1. The real mode compiler generates an instruction like this: CALL [[segment:offset addressing (x86)|<segment>:<offset>]] -> 9A <offlow><offhigh><seglow><seghigh> with <seglow><seghigh> normally being defined as an address that must be fixed up at load time depending on the address where the code has been placed. […] 2. The Geos linker turns this into something else: INT 8xh -> CD 8x […] DB <seghigh>,<offlow>,<offhigh> […] Note that this is again five bytes, so it can be fixed up "in place". Now the problem is that an interrupt requires two bytes, while a CALL FAR instruction only needs one. As a result, the 32-bit vector (<seg><ofs>) must be compressed into 24 bits. […] This is achieved by two things: First, the <seg> address is encoded as a "handle" to the segment, whose lowest [[nibble]] is always zero. This saves four bits. In addition […] the remaining four bits go into the low nibble of the interrupt vector, thus creating anything from INT 80h to 8Fh. […] The interrupt handler for all those vectors is the same. It will "unpack" the address from the three-and-a-half byte notation, look up the absolute address of the segment, and forward the call, after having done its virtual memory loading thing... Return from the call will also pass through the corresponding unlocking code. […] The low nibble of the interrupt vector (80h–8Fh) holds bit 4 through 7 of the segment handle. Bit 0 to 3 of a segment handle are (by definition of a Geos handle) always 0. […] all Geos API run through the "overlay" scheme […]: when a Geos application is loaded into memory, the loader will automatically replace calls to functions in the system libraries by the corresponding INT-based calls. Anyway, these are not constant, but depend on the handle assigned to the library's code segment. […] Geos was originally intended to be converted to [[protected mode]] very early on […], with [[real mode]] only being a "legacy option" […] almost every single line of assembly code is ready for it […]}}
* {{cite web |title=Re: [fd-dev] ANNOUNCE: CuteMouse 2.0 alpha 1 |author-first=Matthias R. |author-last=Paul |work=freedos-dev |date=2002-04-11 |url=https://marc.info/?l=freedos-dev&m=101853130816682&w=2 |access-date=2020-02-21 |url-status=live |archive-url=https://web.archive.org/web/20200221130238/https://marc.info/?l=freedos-dev&m=101853130816682&w=2 |archive-date=2020-02-21 |quote=[…] in case of such mangled pointers […] many years ago Axel<!-- Axel C. Frinke --> and I were thinking about a way how to use *one* entry point into a driver for multiple interrupt vectors (as this would save us a lot of space for the multiple entry points and the more or less identical startup/exit framing code in all of them), and then switch to the different interrupt handlers internally. For example: 1234h:0000h […] 1233h:0010h […] 1232h:0020h […] 1231h:0030h […] 1230h:0040h […] all point to exactly the same entry point. If you hook INT 21h onto 1234h:0000h and INT 2Fh onto 1233h:0010h, and so on, they would all go through the same "loophole", but you would still be able to distinguish between them and branch into the different handlers internally. Think of a "compressed" entry point into a [[A20 line|A20]] stub for [[high memory area|HMA]] loading. This works as long as no program starts doing segment:offset magics. […] Contrast this with the opposite approach to have multiple entry points (maybe even supporting [[IBM]]'s [[IBM Interrupt Sharing Protocol|Interrupt Sharing Protocol]]), which consumes much more memory if you hook many interrupts. […] We came to the result that this would most probably not be save in practise because you never know if other drivers normalize or denormalize pointers, for what reasons ever. […]}} (NB. Something similar to "[[fat pointer]]s" specifically for [[Intel]]'s [[real-mode]] [[segment:offset addressing (x86)|segment:offset addressing]] on [[x86]] processors, containing both a deliberately denormalized pointer to a shared code entry point and some info to still distinguish the different callers in the shared code. While, in an [[open system (computing)|open system]], pointer-normalizing 3rd-party instances (in other drivers or applications) cannot be ruled out completely on [[public interface]]s, the scheme can be used safely on internal interfaces to avoid redundant entry code sequences.)
*{{cite web |title=Re: [fd-dev] ANNOUNCE: CuteMouse 2.0 alpha 1 |author-first=Matthias R. |author-last=Paul |work=freedos-dev |date=2002-04-11 |url=https://marc.info/?l=freedos-dev&m=101853130816682&w=2 |access-date=2020-02-21 |url-status=live |archive-url=https://web.archive.org/web/20200221130238/https://marc.info/?l=freedos-dev&m=101853130816682&w=2 |archive-date=2020-02-21 |quote=[…] in case of such mangled pointers […] many years ago Axel<!-- Axel C. Frinke --> and I were thinking about a way how to use *one* entry point into a driver for multiple interrupt vectors (as this would save us a lot of space for the multiple entry points and the more or less identical startup/exit framing code in all of them), and then switch to the different interrupt handlers internally. For example: 1234h:0000h […] 1233h:0010h […] 1232h:0020h […] 1231h:0030h […] 1230h:0040h […] all point to exactly the same entry point. If you hook INT 21h onto 1234h:0000h and INT 2Fh onto 1233h:0010h, and so on, they would all go through the same "loophole", but you would still be able to distinguish between them and branch into the different handlers internally. Think of a "compressed" entry point into a [[A20 line|A20]] stub for [[high memory area|HMA]] loading. This works as long as no program starts doing segment:offset magics. […] Contrast this with the opposite approach to have multiple entry points (maybe even supporting [[IBM]]'s [[IBM Interrupt Sharing Protocol|Interrupt Sharing Protocol]]), which consumes much more memory if you hook many interrupts. […] We came to the result that this would most probably not be save in practise because you never know if other drivers normalize or denormalize pointers, for what reasons ever. […]}} (NB. Something similar to "[[fat pointer]]s" specifically for [[Intel]]'s [[real-mode]] [[segment:offset addressing (x86)|segment:offset addressing]] on [[x86]] processors, containing both a deliberately denormalized pointer to a shared code entry point and some info to still distinguish the different callers in the shared code. While, in an [[open system (computing)|open system]], pointer-normalizing 3rd-party instances (in other drivers or applications) cannot be ruled out completely on [[public interface]]s, the scheme can be used safely on internal interfaces to avoid redundant entry code sequences.)
* {{cite journal |title=C's Biggest Mistake |author-first=Walter |author-last=Bright |author-link=Walter Bright |date=2009-12-22 |journal=[[Digital Mars]] |url=https://digitalmars.com/articles/C-biggest-mistake.html |access-date=2022-07-11 |url-status=live |archive-url=https://web.archive.org/web/20220608050019/https://www.digitalmars.com/articles/C-biggest-mistake.html |archive-date=2022-06-08}} [<!-- https://www.drdobbs.com/architecture-and-design/cs-biggest-mistake/228701625 -->https://web.archive.org/web/20220711181007/https://www.drdobbs.com/architecture-and-design/cs-biggest-mistake/228701625]
*{{cite journal |title=C's Biggest Mistake |author-first=Walter |author-last=Bright |author-link=Walter Bright |date=2009-12-22 |journal=[[Digital Mars]] |url=https://digitalmars.com/articles/C-biggest-mistake.html |access-date=2022-07-11 |url-status=live |archive-url=https://web.archive.org/web/20220608050019/https://www.digitalmars.com/articles/C-biggest-mistake.html |archive-date=2022-06-08}} [<!-- https://www.drdobbs.com/architecture-and-design/cs-biggest-mistake/228701625 -->https://web.archive.org/web/20220711181007/https://www.drdobbs.com/architecture-and-design/cs-biggest-mistake/228701625]
* {{cite web |title=A Fat Pointer Library |author-first=Daniel |author-last=Holden |date=2015 |work=Cello: High Level C |url=https://libcello.org/learn/a-fat-pointer-library |access-date=2022-07-11 |url-status=live |archive-url=https://web.archive.org/web/20220711181009/https://libcello.org/learn/a-fat-pointer-library |archive-date=2022-07-11}}
*{{cite web |title=A Fat Pointer Library |author-first=Daniel |author-last=Holden |date=2015 |work=Cello: High Level C |url=https://libcello.org/learn/a-fat-pointer-library |access-date=2022-07-11 |url-status=live |archive-url=https://web.archive.org/web/20220711181009/https://libcello.org/learn/a-fat-pointer-library |archive-date=2022-07-11}}
 
{{DEFAULTSORT:Dynamic Dispatch}}[[Category: बहुरूपता (कंप्यूटर विज्ञान)]] [[Category: विधि (कंप्यूटर प्रोग्रामिंग)]]
 


{{DEFAULTSORT:Dynamic Dispatch}}


[[Category: Machine Translated Page]]
[[Category:All articles with unsourced statements|Dynamic Dispatch]]
[[Category:Created On 16/02/2023]]
[[Category:Articles with hatnote templates targeting a nonexistent page|Dynamic Dispatch]]
[[Category:Articles with invalid date parameter in template|Dynamic Dispatch]]
[[Category:Articles with unsourced statements from July 2022|Dynamic Dispatch]]
[[Category:Articles with unsourced statements from October 2018|Dynamic Dispatch]]
[[Category:Articles with unsourced statements from जुलाई 2022|Dynamic Dispatch]]
[[Category:CS1|Dynamic Dispatch]]
[[Category:Machine Translated Page|Dynamic Dispatch]]
[[Category:Pages with script errors|Dynamic Dispatch]]
[[Category:Short description with empty Wikidata description|Dynamic Dispatch]]
[[Category:Template documentation pages|Short description/doc]]
[[Category:Templates Vigyan Ready|Dynamic Dispatch]]

Latest revision as of 10:36, 23 February 2023

कंप्यूटर विज्ञान में, गतिशील प्रेषण एक बहुरूपता (कंप्यूटर विज्ञान) संचालन (विधि (कंप्यूटर प्रोग्रामिंग) या फ़ंक्शन) के कार्यान्वयन को रन टाइम (प्रोग्राम जीवनचक्र चरण) पर कॉल करने की प्रक्रिया है। यह सामान्यतः ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग (OOP) भाषाओं और प्रणालियों में कार्यरत है, और इसकी एक प्रमुख विशेषता मानी जाती है।[1]

ऑब्जेक्ट-ओरिएंटेड सिस्टम एक समस्या को अंतःक्रिया ऑब्जेक्ट्स के एक सेट के रूप में मॉडल करते हैं जो नाम से संदर्भित संचालन को लागू करते हैं। बहुरूपता वह परिघटना है जिसमें कुछ विनिमेय वस्तुएं प्रत्येक एक ही नाम के एक संचालन को उजागर करती हैं लेकिन संभवतः व्यवहार में भिन्न होती हैं। एक उदाहरण के रूप में, ए फाइल वस्तु और ए डेटाबेस वस्तु दोनों में एक है स्टोर रिकॉर्ड विधि जिसका उपयोग भंडारण के लिए कार्मिक रिकॉर्ड लिखने के लिए किया जा सकता है। उनके कार्यान्वयन भिन्न हैं। एक प्रोग्राम एक वस्तु के लिए एक संदर्भ रखता है जो या तो एक फाइल हो सकता है फाइल वस्तु या ए डेटाबेस वस्तु यह कुछ भी हो सकता है, एक रन-टाइम सेटिंग द्वारा निर्धारित किया गया हो, और इस स्तर पर, प्रोग्राम को पता नहीं हो सकता है या परवाह नहीं है। जब प्रोग्राम कॉल करता है तो स्टोर रिकॉर्ड वस्तु पर, कुछ को चुनने की जरूरत है कि कौन सा व्यवहार अधिनियमित हो। यदि कोई OOP को ऑब्जेक्ट को भेजे जाने वाले संदेश के रूप में सोचता है, तो इस उदाहरण में प्रोग्राम एक भेजता है, स्टोर रिकॉर्ड किसी अज्ञात प्रकार के ऑब्जेक्ट को संदेश को सही ऑब्जेक्ट पर भेजने के लिए इसे रन-टाइम सपोर्ट सिस्टम पर छोड़ देता है। वस्तु जो भी व्यवहार लागू करती है।[2]

गतिशील प्रेषण स्थिर प्रेषण के विपरीत है, जिसमें एक बहुरूपी संचालन के कार्यान्वयन को संकलन समय पर चुना जाता है। गतिशील प्रेषण का उद्देश्य एक उपयुक्त कार्यान्वयन के चयन को तब तक टाला जाता है जब तक कि रन टाइम प्रकार का पैरामीटर (या एकाधिक पैरामीटर) ज्ञात न हो जाए। गतिशील विधि प्रेषण एक ऐसा तरीका है, जो प्रोग्राम के रनटाइम में ये तय करता है कि किसी ऑब्जेक्ट के रेफ़्रेन्स में कौनसा मेथड एक्सेक्यूटे होगा ना कि कम्पाइल टाइम में गतिशील विधि प्रेषण इसीलिए महत्वपूर्ण है क्योंकि यही वह तरीका है जिससे जावा रन टाइम बहुरूपता को कार्यान्वित करता है।

गतिशील प्रेषण लेट बाइंडिंग (गतिशील बाइंडिंग के रूप में भी जाना जाता है) से अलग है। नाम बाइंडिंग एक नाम को एक संचालन के साथ जोड़ता है। एक बहुरूपी संचालन में कई कार्यान्वयन होते हैं, जो सभी एक ही नाम से जुड़े होते हैं। बाइंडिंग को संकलित समय पर या (देर से बाइंडिंग के साथ) रन टाइम पर बनाया जा सकता है। गतिशील प्रेषण के साथ, संचालन के एक विशेष कार्यान्वयन को रन टाइम पर चुना जाता है। जबकि गतिशील प्रेषण में लेट बाइंडिंग नहीं होती है, लेट बाइंडिंग गतिशील प्रेषण का संकेत देती है, क्योंकि लेट-बाउंड संचालन के कार्यान्वयन को रन टाइम तक नहीं जाना जाता है।[citation needed]


सिंगल और मल्टीपल प्रेषण

कॉल करने की विधि के किसी संस्करण का विकल्प या तो एक वस्तु पर या वस्तुओं के संयोजन पर आधारित हो सकता है। पहले वाले को सिंगल प्रेषण कहा जाता है और यह सामान्य ऑब्जेक्ट-ओरिएंटेड भाषाओं जैसे स्मॉलटाक, C++, जावा (प्रोग्रामिंग भाषा), सी शार्प (प्रोग्रामिंग लैंग्वेज), सी#, ऑब्जेक्टिव सी, स्विफ्ट (प्रोग्रामिंग भाषा), जावास्क्रिप्ट और सीधे समर्थित है। पायथन (प्रोग्रामिंग भाषा) इन और इसी तरह की भाषाओं में, एक समान सिंटैक्स के साथ डिवीजन (गणित) के लिए एक विधि कह सकते हैं

dividend.divide(divisor)  # dividend / divisor

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

इसके विपरीत, कुछ भाषाएँ ऑपरेंड के संयोजन के आधार पर विधियों या कार्यों को प्रेषित करती हैं; विभाजन प्रकरण में, लाभांश और भाजक के प्रकार एक साथ निर्धारित करते हैं कि कौन सा विभाजन संचालन किया जाएगा। इसे एकाधिक प्रेषण के रूप में जाना जाता है। एकाधिक प्रेषण का समर्थन करने वाली भाषाओं के उदाहरण कॉमन लिस्प, डायलन और जूलिया हैं।

गतिशील प्रेषण तंत्र

विभिन्न गतिशील प्रेषण तंत्रों के साथ एक भाषा लागू की जा सकती है। किसी भाषा द्वारा प्रदान किए गए गतिशील प्रेषण तंत्र के विकल्प काफी सीमा तक उन प्रोग्रामिंग प्रतिमानों को बदल देते हैं जो किसी भाषा में उपलब्ध हैं या उपयोग करने के लिए सबसे स्वाभाविक हैं।

सामान्यतः, एक टाइप की गई भाषा में, प्रेषण तंत्र तर्कों के प्रकार के आधार पर किया जाएगा (सामान्यतः संदेश के प्राप्तकर्ता के प्रकार के आधार पर)। कमजोर या कोई टाइपिंग सिस्टम वाली भाषाएं प्रायः प्रत्येक वस्तु के लिए वस्तु डेटा के भाग के रूप में एक प्रेषण तालिका ले जाती हैं। यह त्वरित व्यवहार की अनुमति देता है क्योंकि प्रत्येक त्वरित किसी दिए गए संदेश को एक अलग विधि में मैप कर सकता है।

कुछ भाषाएँ हाइब्रिड दृष्टिकोण प्रदान करती हैं।

गतिशील प्रेषण में सदैव एक ओवरहेड होता है इसलिए कुछ भाषाएँ विशेष तरीकों के लिए स्थैतिक प्रेषण की पेशकश करती हैं।

C++ कार्यान्वयन

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

C++ कंपाइलर्स सामान्यतः वर्चुअल विधि तालिका (वी टेबल) नामक डेटा संरचना के साथ गतिशील प्रेषण को कार्यान्वित करते हैं जो किसी दिए गए वर्ग के लिए सदस्य फ़ंक्शन पॉइंटर्स के सेट के रूप में नाम-से-कार्यान्वयन मैपिंग को परिभाषित करता है। (यह विशुद्ध रूप से एक कार्यान्वयन विवरण है; C ++ विनिर्देश वी टेबलs का उल्लेख नहीं करता है।) उस प्रकार के उदाहरण तब इस तालिका में उनके उदाहरण डेटा के भाग के रूप में एक सूचक को संग्रहीत करेंगे। यह जटिल है जब एकाधिक वंशानुक्रम का उपयोग किया जाता है। चूंकि C++ देर से बाध्यकारी का समर्थन नहीं करता है, C++ ऑब्जेक्ट में वर्चुअल टेबल को रन-टाइम पर संशोधित नहीं किया जा सकता है, जो प्रेषण लक्ष्य के संभावित सेट को संकलन समय पर चुने गए सीमित सेट तक सीमित करता है।

टाइप ओवरलोडिंग C++ में गतिशील प्रेषण का उत्पादन नहीं करता है क्योंकि भाषा संदेश पैरामीटर के प्रकारों को औपचारिक संदेश नाम का हिस्सा मानती है। इसका मतलब यह है कि प्रोग्रामर जो संदेश नाम देखता है वह बाइंडिंग के लिए उपयोग किया जाने वाला औपचारिक नाम नहीं है।

Go और Rust कार्यान्वयन

Go (प्रोग्रामिंग भाषा), Rust (प्रोग्रामिंग भाषा) और निम (प्रोग्रामिंग भाषा) में, प्रारम्भिक बाइंडिंग के अधिक बहुमुखी रूपांतर का उपयोग किया जाता है।

वी टेबल पॉइंटर्स को ऑब्जेक्ट रेफरेंस के साथ 'फैट पॉइंटर्स' (गो में 'अंतरापृष्ठ', या रस्ट में 'ट्रेट ऑब्जेक्ट्स') के रूप में ले जाया जाता है।[citation needed]

यह अंतर्निहित डेटा संरचनाओं से समर्थित अंतरापृष्ठ को अलग करता है। प्रत्येक संकलित लाइब्रेरी को किसी प्रकार का सही ढंग से उपयोग करने के लिए समर्थित अंतरापृष्ठ की पूरी श्रृंखला को जानने की आवश्यकता नहीं है, केवल विशिष्ट व्यवहार्य लेआउट जिसकी उन्हें आवश्यकता होती है। कोड अलग-अलग अंतरापृष्ठ को अलग-अलग कार्यों के लिए डेटा के एक ही टुकड़े में पास कर सकता है। यह बहुमुखी प्रतिभा प्रत्येक वस्तु संदर्भ के साथ अतिरिक्त डेटा की कीमत पर आती है, जो कि समस्याग्रस्त है यदि ऐसे कई संदर्भों को लगातार संग्रहीत किया जाता है।फैट पॉइंटर शब्द केवल अतिरिक्त संबंधित जानकारी के साथ एक पॉइंटर (कंप्यूटर प्रोग्रामिंग) को संदर्भित करता है। अतिरिक्त जानकारी ऊपर वर्णित गतिशील प्रेषण के लिए एक व्यवहार्य सूचक हो सकती है, लेकिन अधिक सामान्य रूप से संबंधित वस्तु का आकार वर्णन करने के लिए एक टुकड़ा है।[citation needed]


स्मालटॉक कार्यान्वयन

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

क्योंकि एक प्रकार में आधार प्रकार की श्रृंखला हो सकती है, यह लुक-अप महंगा हो सकता है। स्मॉलटाक के तंत्र का एक सरल कार्यान्वयन C++ की तुलना में काफी अधिक ओवरहेड प्रतीत होता है और यह ओवरहेड प्रत्येक ऑब्जेक्ट को प्राप्त होने वाले प्रत्येक संदेश के लिए खर्च किया जाएगा।

रियल स्मॉलटाक कार्यान्वयन प्रायः इनलाइन कैशिंग नामक तकनीक का उपयोग करते हैं[3]यह विधि प्रेषण को बहुत तेज़ बनाता है। इनलाइन कैशिंग मूल रूप से कॉल साइट के पिछले डेस्टिनेशन मेथड एड्रेस और ऑब्जेक्ट क्लास (या मल्टी-वे कैशिंग के लिए कई जोड़े) को स्टोर करता है। विधि चयनकर्ता के आधार पर कैश्ड विधि को सबसे आम लक्ष्य विधि (या केवल कैश मिस हैंडलर) के साथ प्रारंभ किया गया है। जब विधि कॉल साइट निष्पादन के दौरान पहुंच जाती है, तो यह केवल कैश में पते को कॉल करती है। (गतिशील कोड जनरेटर में, यह कॉल एक डायरेक्ट कॉल है क्योंकि डायरेक्ट एड्रेस कैश मिस लॉजिक द्वारा वापस पैच किया जाता है।) कॉल किए गए तरीके में प्रोलॉग कोड फिर कैश्ड क्लास की तुलना वास्तविक ऑब्जेक्ट क्लास से करता है, और यदि वे मेल नहीं खाते हैं , कक्षा में सही विधि खोजने के लिए एक कैश मिस हैंडलर को निष्पादन शाखाएँ। एक तेज़ कार्यान्वयन में कई कैश प्रविष्टियाँ हो सकती हैं और प्रारंभिक कैश मिस पर सही तरीके से निष्पादन प्राप्त करने के लिए प्रायः केवल कुछ निर्देशों की आवश्यकता होती है। सामान्य मामला एक कैश्ड क्लास मैच होगा, और विधि में निष्पादन जारी रहेगा।

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

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

पाइथन (प्रोग्रामिंग लैंग्वेज), रूबी (प्रोग्रामिंग भाषा), ऑब्जेक्टिव-सी और ग्रूवी (प्रोग्रामिंग भाषा) सहित कई अन्य गतिशील रूप से टाइप की गई भाषाएँ समान दृष्टिकोण का उपयोग करती हैं।


पायथन में उदाहरण

class Cat:
    def speak(self):
        print("Meow")

class Dog:
    def speak(self):
        print("Woof")


def speak(pet):
    # Dynamically dispatches the speak method
    # pet can either be an instance of Cat or Dog
    pet.speak()

cat = Cat()
speak(cat)
dog = Dog()
speak(dog)

C++ में उदाहरण

#include <iostream>

// make Pet an abstract virtual base class
class Pet {
public:
    virtual void speak() = 0;
};

class Dog : public Pet {
public:
    void speak() override
    {
        std::cout << "Woof!\n";
    }
};

class Cat : public Pet {
public:
    void speak() override
    {
        std::cout << "Meow!\n";
    }
};

// speak() will be able to accept anything deriving from Pet
void speak(Pet& pet)
{
    pet.speak();
}

int main()
{
    Dog fido;
    Cat simba;
    speak(fido);
    speak(simba);
    return 0;
}

यह भी देखें

संदर्भ

  1. Milton, Scott; Schmidt, Heinz W. (1994). Dynamic Dispatch in Object-Oriented Languages (Technical report). Vol. TR-CS-94-02. Australian National University. CiteSeerX 10.1.1.33.4292.
  2. Driesen, Karel; Hölzle, Urs; Vitek, Jan (1995). "Message Dispatch on Pipelined Processors". ECOOP’95 — Object-Oriented Programming, 9th European Conference, Åarhus, Denmark, August 7–11, 1995. Lecture Notes in Computer Science. Vol. 952. Springer. CiteSeerX 10.1.1.122.281. doi:10.1007/3-540-49538-X_13. ISBN 3-540-49538-X.
  3. Müller, Martin (1995). Message Dispatch in Dynamically-Typed Object-Oriented Languages (Master thesis). University of New Mexico. pp. 16–17. CiteSeerX 10.1.1.55.1782.


अग्रिम पठन

  • Lippman, Stanley B. (1996). Inside the C++ Object Model. Addison-Wesley. ISBN 0-201-83454-5.
  • Groeber, Marcus; Di Geronimo, Jr., Edward "Ed"; Paul, Matthias R. (2002-03-02) [2002-02-24]. "GEOS/NDO info for RBIL62?". Newsgroupcomp.os.geos.programmer. Archived from the original on 2019-04-20. Retrieved 2019-04-20. […] The reason Geos needs 16 interrupts is because the scheme is used to convert inter-segment ("far") function calls into interrupts, without changing the size of the code. The reason this is done so that "something" (the kernel) can hook itself into every inter-segment call made by a Geos application and make sure that the proper code segments are loaded from virtual memory and locked down. In DOS terms, this would be comparable to an overlay loader, but one that can be added without requiring explicit support from the compiler or the application. What happens is something like this: […] 1. The real mode compiler generates an instruction like this: CALL <segment>:<offset> -> 9A <offlow><offhigh><seglow><seghigh> with <seglow><seghigh> normally being defined as an address that must be fixed up at load time depending on the address where the code has been placed. […] 2. The Geos linker turns this into something else: INT 8xh -> CD 8x […] DB <seghigh>,<offlow>,<offhigh> […] Note that this is again five bytes, so it can be fixed up "in place". Now the problem is that an interrupt requires two bytes, while a CALL FAR instruction only needs one. As a result, the 32-bit vector (<seg><ofs>) must be compressed into 24 bits. […] This is achieved by two things: First, the <seg> address is encoded as a "handle" to the segment, whose lowest nibble is always zero. This saves four bits. In addition […] the remaining four bits go into the low nibble of the interrupt vector, thus creating anything from INT 80h to 8Fh. […] The interrupt handler for all those vectors is the same. It will "unpack" the address from the three-and-a-half byte notation, look up the absolute address of the segment, and forward the call, after having done its virtual memory loading thing... Return from the call will also pass through the corresponding unlocking code. […] The low nibble of the interrupt vector (80h–8Fh) holds bit 4 through 7 of the segment handle. Bit 0 to 3 of a segment handle are (by definition of a Geos handle) always 0. […] all Geos API run through the "overlay" scheme […]: when a Geos application is loaded into memory, the loader will automatically replace calls to functions in the system libraries by the corresponding INT-based calls. Anyway, these are not constant, but depend on the handle assigned to the library's code segment. […] Geos was originally intended to be converted to protected mode very early on […], with real mode only being a "legacy option" […] almost every single line of assembly code is ready for it […]
  • Paul, Matthias R. (2002-04-11). "Re: [fd-dev] ANNOUNCE: CuteMouse 2.0 alpha 1". freedos-dev. Archived from the original on 2020-02-21. Retrieved 2020-02-21. […] in case of such mangled pointers […] many years ago Axel and I were thinking about a way how to use *one* entry point into a driver for multiple interrupt vectors (as this would save us a lot of space for the multiple entry points and the more or less identical startup/exit framing code in all of them), and then switch to the different interrupt handlers internally. For example: 1234h:0000h […] 1233h:0010h […] 1232h:0020h […] 1231h:0030h […] 1230h:0040h […] all point to exactly the same entry point. If you hook INT 21h onto 1234h:0000h and INT 2Fh onto 1233h:0010h, and so on, they would all go through the same "loophole", but you would still be able to distinguish between them and branch into the different handlers internally. Think of a "compressed" entry point into a A20 stub for HMA loading. This works as long as no program starts doing segment:offset magics. […] Contrast this with the opposite approach to have multiple entry points (maybe even supporting IBM's Interrupt Sharing Protocol), which consumes much more memory if you hook many interrupts. […] We came to the result that this would most probably not be save in practise because you never know if other drivers normalize or denormalize pointers, for what reasons ever. […] (NB. Something similar to "fat pointers" specifically for Intel's real-mode segment:offset addressing on x86 processors, containing both a deliberately denormalized pointer to a shared code entry point and some info to still distinguish the different callers in the shared code. While, in an open system, pointer-normalizing 3rd-party instances (in other drivers or applications) cannot be ruled out completely on public interfaces, the scheme can be used safely on internal interfaces to avoid redundant entry code sequences.)
  • Bright, Walter (2009-12-22). "C's Biggest Mistake". Digital Mars. Archived from the original on 2022-06-08. Retrieved 2022-07-11. [1]
  • Holden, Daniel (2015). "A Fat Pointer Library". Cello: High Level C. Archived from the original on 2022-07-11. Retrieved 2022-07-11.