2009-02-25 16 views
7

The CRTP सुझाया गया है। हालांकि, यह पैटर्न कथित तौर पर स्थैतिक बहुरूपता के लिए उपयोगी है। जिस डिज़ाइन को मैं देख रहा हूं वह आभासी फ़ंक्शन कॉल द्वारा तेज़ी से बाधित हो रहा है, hinted at here. भी 2.5x की गति शानदार होगी।क्या सी ++ में बहुरूपता के विकल्प हैं? गतिशील बहुरूपता के बारे में इस प्रश्न में

प्रश्न में कक्षाएं सरल हैं और पूरी तरह से इनलाइन कोडित की जा सकती हैं, हालांकि यह रनटाइम तक ज्ञात नहीं है जब कक्षाओं का उपयोग किया जाएगा। इसके अलावा, किसी भी क्रम में चोट लगने पर प्रदर्शन अपमान को ढंकना पड़ सकता है।

कोई सुझाव (इस मामले में सीआरटीपी का उपयोग कैसे किया जा सकता है) स्वागत है।

संपादित करें: गूगलिंग फ़ंक्शन टेम्पलेट का उल्लेख बदल जाता है। ये आशाजनक लग रहा है।

उत्तर

3

मैं एम-तेज से सहमत हूं कि आप रनटाइम बहुरूपता से बचने के लिए नहीं जा रहे हैं।

आप लालित्य से अधिक मूल्य अनुकूलन हैं, जैसे

void invoke_trivial_on_all(const std::vector<Base*>& v) 
{ 
    for (int i=0;i<v.size();i++) 
    { 
    if (v[i]->tag==FooTag) 
     static_cast<Foo*>(v[i])->Foo::trivial_virtual_method(); 
    else if (v[i]->tag==BarTag) 
     static_cast<Bar*>(v[i])->Bar::trivial_virtual_method(); 
    else... 
    } 
} 

कुछ के साथ कहते हैं की जगह

void invoke_trivial_on_all(const std::vector<Base*>& v) 
{ 
    for (int i=0;i<v.size();i++) 
    v[i]->trivial_virtual_method(); 
} 

कोशिश यह है नहीं सुंदर, निश्चित रूप से नहीं OOP (अधिक आप अच्छे पुराने में क्या कर सकता करने के लिए एक प्रत्यावर्तन 'सी') लेकिन यदि वर्चुअल विधियां काफी छोटी हैं तो आपको कोई कॉल नहीं मिलना चाहिए (पर्याप्त पर्याप्त कंपाइलर & ऑप्टिमाइज़ेशन विकल्प के अधीन)।डायनामिक_कास्ट या टाइपिड का उपयोग करने वाला एक संस्करण थोड़ा अधिक सुरुचिपूर्ण/सुरक्षित हो सकता है लेकिन सावधान रहें कि उन सुविधाओं का अपना ओवरहेड है जो शायद वर्चुअल कॉल के बराबर है।

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

+1

मेरा मानना ​​है कि अगर टेम्पलेट में स्टेटमेंट्स इस गड़बड़ी को थोड़ा क्लीनर बना सकते हैं। वैसे भी वादा करता है। – casualcoder

+0

कृपया static_cast <> reinterpret_cast <> के बजाय <> का उपयोग करें, बाद वाले कुछ मामलों में गलत परिणाम देंगे (एक सामान्य कार्यान्वयन पर, एक उदाहरण होगा यदि फू या बार में कई आधार वर्ग हैं और बेस उनमें से पहला नहीं है)। –

+0

अच्छा बिंदु धन्यवाद; जवाब अपडेट किया गया। – timday

18

पॉलिमॉर्फिज्म का शाब्दिक अर्थ है एकाधिक (पॉली) रूप (morphs)। सांख्यिकीय रूप से टाइप की गई भाषाओं (जैसे सी ++) में तीन प्रकार के बहुरूपता हैं।

  1. एडोक पॉलीमोर्फिज्म: यह सबसे अच्छा सी ++ में फ़ंक्शन और विधि ओवरलोडिंग के रूप में देखा जाता है। संकलन समय फ़ंक्शन या विधि हस्ताक्षर पर कॉल के पैरामीटर के प्रकार के आधार पर एक ही फ़ंक्शन नाम विभिन्न विधियों से जुड़ जाएगा।
  2. पैरामैट्रिक पॉलिमॉर्फिज्म: सी ++ में यह टेम्पलेट्स और सीआरटीपी, विशेषज्ञता, आंशिक विशेषज्ञता, मेटा प्रोग्रामिंग इत्यादि जैसी सभी मजेदार चीजें हैं। इस तरह के पॉलीमोर्फिज्म फिर से एक ही टेम्पलेट का नाम अलग-अलग चीजें कर सकता है टेम्पलेट पैरामीटर पर संकलन समय पॉलिमॉर्फिज्म है।
  3. सबटाइप पॉलिमॉर्फिज्म: आखिरकार यह वही है जब हम सी ++ में पॉलीमोर्फिज्म शब्द सुनते हैं। यह वह जगह है जहां व्युत्पन्न वर्ग व्यवहार को विशेषज्ञ बनाने के लिए आभासी कार्यों को ओवरराइड करते हैं। बेस क्लास के लिए एक ही प्रकार का पॉइंटर अलग-अलग व्यवहार हो सकता है जो कंक्रीट व्युत्पन्न प्रकार के आधार पर इंगित कर रहा है। रन टाइम सी ++ में पॉलिमॉर्फिज्म पाने का यह तरीका है।

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

वर्चुअल विधि कॉल में स्थिर रूप से बाध्य कॉल पर बहुत छोटा प्रदर्शन ओवरहेड होता है। मैं आपको इस SO question.

-1

के उत्तरों को देखने के लिए आग्रह करता हूं कि आप ओले सी मार्ग पर जा सकते हैं और यूनियनों का उपयोग कर सकते हैं। हालांकि वह भी गन्दा हो सकता है।

+1

मैंने इस तीन अलग-अलग समय को 'प्याज' के रूप में पढ़ा और केवल कल्पना कर सकता था कि आपका 'गन्दा' वर्कफ़्लो क्या शामिल है। –

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