2009-12-10 13 views
17

संकलन-समय बहुरूपता क्या है और यह केवल फ़ंक्शंस पर क्यों लागू होती है?संकलन-समय बहुरूपता क्या है और यह केवल फ़ंक्शंस पर क्यों लागू होती है?

+6

प्रश्न पाठ्यपुस्तक में पूरी तरह से एम्बेडेड दिखता है। –

+2

क्या आप विरोधाभास का वर्णन कर सकते हैं? - हो सकता है कि आपके पास वास्तविक प्रश्न का उत्तर देने में मदद मिले। – johannes

+1

मेरी पाठ्यपुस्तक में कुछ अस्पष्टता है, या मैं जो पढ़ रहा हूं उसे गलत समझ रहा हूं, इसलिए मुझे लगा कि मैं यहां पूछता हूं। – ihtkwot

उत्तर

17

वापस जब "संकलन समय polymorphism" का मतलब समारोह अधिभार था। यह केवल फ़ंक्शंस पर लागू होता है क्योंकि वे सब आप अधिभारित कर सकते हैं।

वर्तमान सी ++ में, टेम्पलेट्स इसे बदलते हैं। नील बटरवर्थ ने पहले ही एक उदाहरण दिया है। एक और टेम्पलेट विशेषज्ञता का उपयोग करता है। - हम एक struct कि प्रत्येक प्रकार के लिए अलग तरह से काम करता है हो रही है

#include <iostream> 
#include <string> 

template <class T> 
struct my_template { 
    T foo; 
    my_template() : foo(T()) {} 
}; 

template <> 
struct my_template<int> { 
    enum { foo = 42 }; 
}; 

int main() { 
    my_template<int> x; 
    my_template<long> y; 
    my_template<std::string> z; 
    std::cout << x.foo << "\n"; 
    std::cout << y.foo << "\n"; 
    std::cout << "\"" << z.foo << "\""; 
    return 0; 
} 

यह 42, 0, और "" (कोई रिक्त स्ट्रिंग) उपज चाहिए: उदाहरण के लिए।

यहां हमारे पास कार्यों के बजाय कक्षाओं का "समयबद्ध बहुरूपता" है। मुझे लगता है कि यदि आप इस बिंदु पर बहस करना चाहते हैं, तो आप दावा कर सकते हैं कि कम से कम एक मामले में यह कम से कम आंशिक रूप से कन्स्ट्रक्टर (एक फ़ंक्शन) का परिणाम है, लेकिन my_template का विशेष संस्करण भी एक कन्स्ट्रक्टर नहीं है।

संपादित करें: यह क्यों polymorphism है। मैंने एक कारण के लिए कोट्स में "संकलन समय polymorphism" रखा - यह सामान्य बहुरूपता से कुछ अलग है।

int value(int x) { return 0; } 
long value(long x) { return 42; } 

std::cout << value(1); 
std::cout << value(1L); 

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

+1

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

+0

आप कैसे तर्क देंगे कि बहुरूपता लागू नहीं होती है? पॉलिमोफिज्म या तो "कई रूपों" का अर्थ है। आपके उदाहरणों में (और funciton अधिभार में) एक ही फ़ंक्शन चयनकर्ता फ़ंक्शन के कई अलग-अलग "रूपों" में परिणाम देता है। –

6

संकलन समय बहुरूपता एक शब्द है कि सी ++ टेम्पलेट प्रोग्रामिंग करने के लिए संदर्भित करता है। उदाहरण के लिए, संकलन समय पर आप इसमें क्या है द्वारा एक std :: वेक्टर की वास्तविक प्रकार का निर्धारण:

std::vector <int> vi; 
std::vector <std::string> vs; 

मुझे यकीन है कि तुम क्यों लगता है कि यह यह कार्यों तक ही सीमित है नहीं कर रहा हूँ।

void foo(int x); 
void foo(float y); 

//Somewhere else 
int x = 3; 
foo(x); //Will call first function 
float y = 2; 
foo(y); //Will call second function 

समारोह:

+0

अधिकतर क्योंकि मुझे अपनी कक्षा में बताया गया था कि यह कार्यों तक ही सीमित था। मैं पूरी तरह से समझ नहीं पा रहा हूं कि यह केवल कार्यों तक सीमित क्यों है। – ihtkwot

+1

@ नील मैं आपके साथ सहमत हूं। कक्षा टेम्पलेट्स संकलन समय polymorphism exibit भी प्रतीत होता है। – captonssj

13

संकलन समय बहुरूपता एक साथ आमतौर पर सच है कि आप एक ही नाम और संकलक के साथ एक कई कार्य हो सकता है जो एक तर्क के आधार पर इस्तेमाल किया संकलन समय पर चयन करेंगे इसका मतलब है foo को अधिभारित कहा जाता है। विभिन्न प्रकार के टेम्पलेट इंस्टेंटेशन को संकलन समय बहुरूपता भी कहा जा सकता है।

+0

अरे, मुझे इसे हराया। – wheaties

+0

कक्षा टेम्पलेट्स के बारे में क्या? कंपाइलर क्लास के किस संस्करण को हमारे द्वारा प्रदान किए जाने वाले प्रकार टी के आधार पर तत्काल करने के लिए चुनता है, तो क्या इसका मतलब क्लास टेम्पलेट्स संकलित समय पॉलीमोर्फिक व्यवहार को भी समाप्त करता है? – captonssj

+0

@captonssj, मैं कहूंगा कि हाँ, वे करते हैं। – Omnifarious

6

जो चीज केवल फ़ंक्शंस पर लागू होती है वह टेम्पलेट पैरामीटर कटौती है। अगर मैं एक समारोह टेम्पलेट है:

template <typename T> 
void foo(T &t); 

तब मैं int a = 0; foo(a); कर सकते हैं, और इस int a = 0; foo<int>(a); के बराबर होगी। कंपाइलर काम करता है कि मेरा मतलब है foo<int>। कम से कम, यह काम करता है कि इसे foo<int> का उपयोग करना चाहिए - अगर ऐसा नहीं है तो मेरा मतलब है कि मेरे लिए दुर्भाग्य है, और मैं foo<unsigned int>(a); या जो कुछ भी लिख सकता था।

हालांकि, अगर मैं एक वर्ग टेम्पलेट है:

template <typename T> 
struct Foo { 
    T &t; 
    Foo(T &t) : t(t) {} 
    T &getT() { return t; } 
}; 

तब मैं int a = 0; Foo(a).getT(); नहीं कर सकते। मुझे Foo<int>(a) निर्दिष्ट करना होगा। कंपाइलर को यह काम करने की अनुमति नहीं है कि मेरा मतलब Foo<int> है।

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

क्यों यह मामला है - मानक कहता है, मुझे नहीं पता क्यों। सामान्य संदिग्ध (ए) लागू करना बहुत मुश्किल है, (बी) मानक समिति की राय में यह उपयोगी नहीं है, या (सी) यह भाषा में कहीं और विरोधाभास या अस्पष्टता बनाता है।

लेकिन आप अभी भी वर्ग के साथ बहुरूपता के अन्य प्रकार कर सकते हैं:

template <typename T> 
struct Foo { 
    T &t; 
    Foo(T &t): t(t) {} 
    void handleMany(int *ra, size_t s) { 
     for (size_t i = 0; i < s; ++i) { 
      t.handleOne(ra[i]); 
     } 
    } 
}; 

यह आमतौर पर भी संकलन समय बहुरूपता कहा जाता है, क्योंकि जहाँ तक टेम्पलेट के लेखक का संबंध है, t.handleOne कुछ भी हो सकता है, और जब आवश्यक हो तो इसे हल किया जाएगा, जब बाद में "फू को तत्काल" संकलन में संकलित किया जाएगा।

+0

मुझे लगता है कि यह मानक समिति के अनुसार उपयोगी है, क्योंकि उन्होंने std :: mem_fun/std :: mem_fun_t के कार्यान्वयन के साथ इस विशिष्ट समस्या के आसपास काम करना चुना है।मूल रूप से वे क्या किया था: टेम्पलेट std :: mem_fun_t <_Tx> mem_fun (स्थिरांक _Tx एंड टी) { वापसी std :: mem_fun_t <_Tx> (टी); } –

+0

हां, और इटेटरेटर एडाप्टर के साथ ही: 'back_inserter' 'back_insert_iterator' देता है। जब मैंने कहा "और", मेरा मतलब था "यह सब सच है" के बजाय, "यह सूची है"। मुझे लगता है कि (ए) भी असंभव है, इसलिए यह या तो (सी) या "कोई अच्छा कारण नहीं है"। –

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