2016-03-25 10 views
8

के बिना पॉलिमॉर्फिक फ़ंक्शन कॉल मान लीजिए कि पदानुक्रम के सभी वर्ग टेम्पलेट सदस्य फ़ंक्शन g लागू करते हैं। कैसे मैं डुप्लिकेट कोड से छुटकारा और अभी भी प्राप्त कर सकते हैंडुप्लिकेट कोड

struct A { 
    virtual void f1() { 
     g(5); 
    } 
    virtual void f2() { 
     g(5.5); 
    } 
private: 
    template <typename T> void g(T) {std::cout << "In A" << std::endl;} 
}; 

struct B: A { 
    // Can I get rid of this duplicate code? 
    virtual void f1() { 
     g(5); 
    } 
    virtual void f2() { 
     g(5.5); 
    } 
private: 
    template <typename T> void g(T) {std::cout << "In B" << std::endl;} 
}; 

struct C: A { 
    // Can I get rid of this duplicate code? 
    virtual void f1() { 
     g(5); 
    } 
    virtual void f2() { 
     g(5.5); 
    } 
private: 
    template <typename T> void g(T) {std::cout << "In C" << std::endl;} 
}; 

int main() 
{ 
    B b; 
    A &a = b; 
    a.f1(); 
    return 0; 
} 

f1 और f2 के कार्यान्वयन के बाद से सभी वर्गों में समान हैं,: सभी वर्गों दो अन्य कार्यों f1 और f2 कि इस टेम्पलेट फोन का एक ही कार्यान्वयन का हिस्सा main में पॉलिमॉर्फिक कॉल अपेक्षित काम करता है (यानी आउटपुट "बी में" उत्पादन)?

उत्तर

3

ध्यान दें कि f1 और f2A में, B, और C के कार्यान्वयन नहीं समान हैं। आइए इसे f1 एस तक सीमित करें। एक ::A::g<int> नामक फ़ंक्शन को कॉल करता है, दूसरा एक ::B::g<int> नामक फ़ंक्शन को कॉल करता है, और तीसरा व्यक्ति ::C::g<int> नामक फ़ंक्शन को कॉल करता है। वे समान से बहुत दूर हैं। (अपने उदाहरण में)

template <class Derived> 
struct DelegateToG : public A 
{ 
    void f1() override 
    { 
    static_cast<Derived*>(this)->g(5); 
    } 

    void f2() override 
    { 
    static_cast<Derived*>(this)->g(5.5); 
    } 
}; 

class B : public DelegateToG<B> 
{ 
    friend DelegateToG<B>; 
private: 
    template <class T> void g(T) { /*...*/ } 
}; 

class C : public DelegateToG<C> 
{ 
    friend DelegateToG<C>; 
private: 
    template <class T> void g(T) { /*...*/ } 
}; 
+0

मैंने इसे दूसरे तरीके से देखो: उन सभी को फोन 'इस-> जी ', जहां '* this'' A' के गतिशील प्रकार है। यह देखने का गलत तरीका क्यों है? – AlwaysLearning

+1

@ हमेशा के लिए सीखना क्योंकि 'जी' वर्चुअल (और नहीं हो सकता) वर्चुअल है, जिसका अर्थ यह है कि सामान्य संकलन-समय नियम लागू होते हैं। ध्यान दें कि संकलन-समय नियम C++ में डिफ़ॉल्ट हैं। इसमें केवल कुछ चुनिंदा अपवाद हैं ('वर्चुअल', 'गतिशील_कास्ट',' टाइपिड')। – Angew

+0

दाएं। लेकिन 'एफ 1' वर्चुअल है। 'F1' के भीतर' this' का प्रकार 'ए' का गतिशील प्रकार है। मैं चाहता हूं कि व्युत्पन्न कक्षा में कार्यान्वयन को दोहराने के बिना व्युत्पन्न कक्षा में 'f1' का समान समान कार्यान्वयन हो ... – AlwaysLearning

1

तुम सिर्फ वर्ग विशेष बातें टेम्पलेट समारोह का उपयोग करता है, इस तरह के रूप में बाहर कारक बन सकते हैं वर्ग के नाम:

सबसे अच्छा तुम कर सकते हो एक CRTP शैली आधार है :

#include <iostream> 
using namespace std; 

class A 
{ 
private: 
    virtual auto classname() const -> char const* { return "A"; } 

protected: 
    template <typename T> void g(T) {cout << "In " << classname() << endl;} 

public: 
    virtual void f1() { g(5); } 
    virtual void f2() { g(5.5); } 
}; 

class B 
    : public A 
{ 
private: 
    auto classname() const -> char const* override { return "B"; } 
}; 

class C 
    : public A 
{ 
private: 
    auto classname() const -> char const* override { return "C"; } 
}; 

auto main() 
    -> int 
{ static_cast<A&&>(B()).f1(); } 
+0

यह सिर्फ एक उदाहरण था। वास्तव में, 'जी' के कार्यान्वयन बहुत भिन्न होते हैं। – AlwaysLearning

+0

@ हमेशा के लिए सीखना: मैं ऐसे प्रश्न का उत्तर नहीं दे सकता जिसे आपने नहीं देखा है। माफ़ कीजिये। टेलीपैथिक नहीं –

+0

आप बिल्कुल सही हैं। – AlwaysLearning

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