2012-05-11 13 views
8

हाय सब मुझे टेम्पलेट्स और बहुरूपता के बारे में संदेह है। परिभाषा के अनुसार बहुरूपता कोड पुन: प्रयोज्यता प्रदान करती है, और कुछ अर्थों में टेम्पलेट्स उपयोगकर्ता को विभिन्न डेटा प्रकारों के साथ सामान्य प्रोग्रामिंग प्रदान करके एक ही कोड का उपयोग करने की अनुमति देता है। तो टेम्पलेट्स पर बहुरूपता का उपयोग करने का क्या फायदा है। यह एक मूर्ख सवाल हो सकता है लेकिन मैं सही अंतर जानने के लिए उत्सुक हूं।टेम्पलेट्स और बहुरूपता के बीच क्या अंतर है

+1

टेम्पलेट स्थिर/संकलित समय polymorphism प्रदान करते हैं। जबकि * आभासीवाद * गतिशील बहुरूपता प्रदान करता है। –

+1

क्या अलग है? सब कुछ। पॉलीमोर्फिज्म कोड पुन: प्रयोज्यता के बारे में भी दूरस्थ रूप से नहीं है। टेम्पलेट्स हैं। –

+1

@MooingDuck: पॉलीमोर्फिज्म कोड को फिर से उपयोग करने की अनुमति देता है। पुराने कोड (एक पॉलिमॉर्फिक बेस क्लास के खिलाफ लिखा गया) नया कोड (उसी बेस क्लास की ओर लिखा गया) का उपयोग कर। –

उत्तर

11

आपको गलत समझा जाता है कि बहुरूपता क्या है।

पॉलिमॉर्फिज्म, इसके मूल में, व्युत्पन्न कक्षाओं के साथ कुछ लेना देना नहीं है। पॉलिमॉर्फिज्म का अर्थ केवल इसके बारे में सबकुछ जानने के बिना किसी प्रकार का उपयोग करने की क्षमता है। एक ठोस प्रकार का उपयोग करने के बजाय, पॉलिमॉर्फिज्म प्रोटोटाइप के कुछ रूपों पर निर्भर करता है कि यह निर्धारित करने के लिए कि किस प्रकार के होते हैं। प्रोटोटाइप फिट करने वाले किसी भी प्रकार को स्वीकार किया जाता है।

सी ++ में रनटाइम पॉलीमोर्फिज्म, वर्चुअल फ़ंक्शन वाले बेस क्लास से कक्षाएं प्राप्त करके प्रदान किया जाता है। बेस क्लास और आभासी फ़ंक्शन पॉलीमोर्फिक प्रोटोटाइप बनाते हैं। बेस वर्च को स्वीकार करने वाले बेस क्लास को स्वीकार करने के लिए लिखा गया कोड बेस क्लास से प्राप्त क्लास इंस्टेंस स्वीकार करेगा।

संकलन समय बहुरूपता संकलन समय पर बहुरूपता ऐसा होता है ...;) इसका मतलब है कि संकलक पता होना चाहिए क्या चल रहा है है। आपने पॉलिमॉर्फिक प्रोटोटाइप के खिलाफ सी ++ कोड लिखा होगा, लेकिन कंपाइलर परवाह नहीं है। आपको पोस्ट-संकलन के बाद विशिष्ट ठोस प्रकार मिलते हैं।

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

आप इस टेम्पलेट समारोह है:

template<typename T> 
void Stuff(T &t) 
{ 
    t.call(15); 
} 

T पर एक निहित आवश्यकता नहीं है। यह आवश्यकता यह है कि इसमें call नामक एक सदस्य फ़ंक्शन है। इस सदस्य फ़ंक्शन का एक एकल अधिभार होना चाहिए जिसे पूर्णांक मान के साथ बुलाया जा सकता है।

इसका मतलब है कि कोई भी इस प्रोटोटाइप के अनुकूल होने के प्रकार का उपयोग किया जा सकता है।

टेम्पलेट पॉलीमोर्फिज्म विरासत बहुरूपता से अधिक व्यापक है, क्योंकि इसे व्यापक प्रकार के प्रकारों द्वारा उपयोग किया जा सकता है। विरासत बहुरूपता का उपयोग करने के लिए विशेष रूप से एक प्रकार का डिजाइन किया जाना चाहिए; आपको कक्षा से निकलना है। एक प्रकार गैर विनाशकारी हो सकता है (यानी: आपको खुद को प्रकार बदलने की ज़रूरत नहीं है) टेम्पलेट polymorphism के लिए अनुकूलित। तो और अधिक यहां तक ​​कि अगर अपने टेम्पलेट प्रोटोटाइप अच्छी तरह से बनाया गया है:

template<typename T> 
void Stuff(T &t) 
{ 
    call(t, 15); 
} 

सब Stuff के इस संस्करण की आवश्यकता है कुछ समारोह है कि एक T& और एक पूर्णांक मूल्य लेता है कि वहाँ है। अगर मेरे पास कुछ प्रकार है जो मैं Stuff के साथ उपयोग करना चाहता हूं, तो मुझे बस एक उचित नामस्थान (0, नामस्थान जिस प्रकार टाइप किया गया था) में call फ़ंक्शन को परिभाषित करना है। और यह ठीक काम करेगा। बिना संशोधित किए बिना सभी प्रकार।

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

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

टेम्पलेट पॉलीमोर्फिज्म बहुत अधिक निहित है। चूंकि सी ++ में प्रोटोटाइप को वर्तनी करने का कोई तरीका नहीं है कि एक विशेष टेम्पलेट फ़ंक्शन/क्लास एक प्रकार पर रखता है, इसलिए किसी टेम्पलेट प्रकार पर गलती से कुछ कॉल करना बहुत आसान है जिसे आपको नहीं करना चाहिए। कंपाइलर केवल तब ही इसका पता लगाएगा जब आप उस प्रकार का उपयोग करने का प्रयास करेंगे जो प्रोटोटाइप में फिट नहीं है। और फिर भी आपको आम तौर पर एक बड़ी त्रुटि स्पू मिल जाएगी (इस पर निर्भर करता है कि आपका टेम्पलेट कोड कितना गहराई से घिरा हुआ है) जिससे यह जानना मुश्किल हो जाता है कि समस्या कहां है।

निहित टेम्पलेट पॉलीमोर्फिक प्रोटोटाइप को लागू करना भी बहुत कठिन है, क्योंकि इसे वर्तनी नहीं दी गई है। व्युत्पन्न वर्ग को कार्यान्वित करने के लिए बेस क्लास के माध्यम से घूमना, सभी वर्चुअल फ़ंक्शंस को देखना और उन्हें कार्यान्वित करना आवश्यक है। टेम्पलेट प्रोटोटाइप के लिए ऐसा करना बहुत मुश्किल है, जब तक वहां कहीं भी दस्तावेज नहीं होता है। यदि आप कुछ लागू करने में विफल रहते हैं, तो आपको फिर से एक त्रुटि स्पू मिलती है जो आम तौर पर समस्या के बारे में आने से कम होती है।

+1

"इस सदस्य फ़ंक्शन का एक एकल ओवरलोड होना चाहिए जिसे पूर्णांक मान के साथ बुलाया जा सकता है।" - और 'int' के साथ कॉल अस्पष्ट नहीं होना चाहिए, और संभवतः कुछ अन्य शर्त जो मैं भूल गया हूं। यही कारण है कि पॉलीमोर्फिक प्रोटोटाइप आमतौर पर "इस अभिव्यक्ति में निम्नलिखित गुण होना चाहिए:" के संदर्भ में दस्तावेज किया गया है। यदि आप इसे किस दस्तावेज़ और ओवरलोड * मौजूद * के संदर्भ में दस्तावेज करने का प्रयास करते हैं तो आप किनारे के सभी प्रकार के मामलों में आते हैं। –

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