2015-07-01 13 views
8

बिना कॉल बच्चे विधि कोड पर विचार करें।आधार विधि से आभासी या संदर्भ

मैं हमेशा से समझ में आ "आभासी" उपयोगी है जब हम बहुरूपता अनुमति देने के लिए एक इंटरफ़ेस चाहते हैं, A *a = new B(); a->f() कहते हैं, लेकिन इस उदाहरण इंगित करता है कि virtual भी इस स्थिति में आवश्यक है। इस उदाहरण की मेरी समझ यह है कि पर A::f पर औपचारिक रूप से this->g() के बराबर है, और यह एक सूचक है।

बहरहाल, यह नहीं है क्या मैं वास्तव में चाहता था: मेरा असली उदाहरण में, मैं एक सामान्य विधि A::simulate (माना A::f) के साथ एक सामान्य टेम्पलेट वर्ग एक है, जो अलग-अलग तरीकों का उपयोग करता (माना A::g()), जिनमें से कुछ अधिलेखित सबक्लास द्वारा (B कहें)। मैं चाहता था कि विधि A::simulate विधि इस तरह से हो कि कोड ए के उप-वर्गों में संकलित किया जाएगा जैसे कि इसे उप-वर्गों पर परिभाषित किया गया है, इसलिए मेरे पास एक ही तर्क को कई बार कोडित नहीं किया गया है। मैं यह कैसे कर सकता हूँ?

ऐसा इसलिए है क्योंकि मेरे इंटरफ़ेस को बहुरूपता की आवश्यकता नहीं होगी क्योंकि उपयोगकर्ता को हमेशा कोड को संकलित करने की आवश्यकता होगी (यानी यह केवल शीर्षलेख है)।

+7

अपने आधार वर्ग एक CRTP टेम्पलेट वर्ग बनाओ। –

+0

क्या आप अलग-अलग शब्दों में समस्या को समझ सकते हैं यदि आप A :: g() वर्चुअल बनाते हैं? –

+0

@ खनल-केविन: मुझे ए :: जी() वर्चुअल क्यों बनाना चाहिए? मेरे लिए, बहुरूपता या इंटरफ़ेस का हिस्सा नहीं है जिसका मैं उत्पादन कर रहा हूं। चूंकि मुझे नहीं लगता कि पॉलिमॉर्फिज्म मेरे विशिष्ट उपयोग मामले में * कैसे मदद करता है *, मेरे पास इसे जोड़ने के लिए एक अनिवार्य कारण नहीं है। मैं जानना चाहता था कि मैं जिस भाषा का उपयोग कर रहा हूं उसके कारण मुझे * वास्तव में * जोड़ने की ज़रूरत है। –

उत्तर

11

आप बस अपनी आधार वर्ग बना सकते हैं एक CRTP (आप उल्लेख किया है के रूप में यह पहले से ही एक टेम्प्लेटेड वर्ग वैसे भी):

#include <iostream> 

template<class Derived> 
class A { 
public: 
    void g() {std::cout << "Call from A" << std::endl;} 
    void f() { static_cast<Derived*>(this)->g();} 
      // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Call g() from Derived 
}; 

class B : public A<B> { 
public: 
    void g() {std::cout << "Call from B" << std::endl;} 
}; 

int main() { 
    B b; 
    b.f(); // "Call from B" 
} 
+2

सुंदर पैटर्न। आपको बहुत - बहुत धन्यवाद! –

+0

@ जे.सी.Leitão हां, यह कई उपयोग मामलों (मिक्स्ड इंटरफेस, नीति आधारित desgns, आदि) के लिए उपयोगी है। एम्बेडेड डिज़ाइन के लिए विशेष रूप से उपयोगी, जहां आप Vtables के साथ अतिरिक्त ओवरहेड से बचना चाहते हैं, और अच्छी तरह से जानते हैं कि आपको रनटाइम कॉन्फ़िगरेशन की आवश्यकता नहीं होगी (लेकिन केवल संकलन समय पर आपके वास्तव में उपलब्ध हार्डवेयर घटकों को कॉन्फ़िगर करें)। –

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