2012-04-08 22 views
8

वर्चुअल सदस्य फ़ंक्शंस के विपरीत व्युत्पन्न क्लास सदस्य फ़ंक्शन पॉइंटर को कैसे पंजीकृत करें, मुझे एक ऐसे समाधान की आवश्यकता है जहां प्रत्येक स्तर के क्लास व्युत्पन्न पर लागू एक फ़ंक्शन बेस क्लास द्वारा बाद में कॉल के लिए पंजीकृत किया जा सके। (न केवल सबसे व्युत्पन्न कार्यान्वयन)बेस क्लास

ऐसा करने के लिए, मैं व्युत्पन्न कक्षाओं के लिए अपने कार्य को पंजीकृत करने के लिए व्युत्पन्न कक्षाओं के लिए एक तंत्र प्रदान करने पर विचार कर रहा था जैसे कि व्युत्पन्न वर्ग निर्माता के दौरान।

मुझे सदस्य फ़ंक्शन पॉइंटर तर्क के साथ समस्या हो रही है। मैं सोच रहा था कि व्युत्पन्न बेस से लिया गया है, this पॉइंटर स्वचालित रूप से डाला जाना चाहिए।

क्या यह मेरी कोशिश के करीब किया जा सकता है या क्या मुझे स्थिर सदस्य कार्य, void *, और static_cast का उपयोग करने की आवश्यकता है?

class Base 
{ 
protected: 
    typedef void (Base::*PrepFn)(int n); 
    void registerPrepFn(PrepFn fn) {}; 
} 

class Derived : public Base 
{ 
    Derived() { 
     registerPrepFn(&Derived::derivedPrepFn); 
    }; 

    void derivedPrepFn(int n) {}; 

} 

संकलक त्रुटि:

error: no matching function for call to 'Derived::registerPrepFn(void (Derived::*)(int))' 
note: candidates are:     'void Base::registerPrepFn(void (Base::*)(int))' 
+1

मुझे यकीन नहीं है कि आप वास्तव में क्या करना चाहते हैं। लेकिन यह निश्चित रूप से इस तरह से संभव नहीं है; 'व्युत्पन्न' में परिभाषित एक सदस्य फ़ंक्शन को 'बेस :: *' द्वारा इंगित नहीं किया जा सकता है। शायद यदि आप शीर्ष-स्तरीय लक्ष्य की व्याख्या करते हैं, तो कोई बेहतर समाधान सुझा सकता है। –

+3

एफटीआर, 'शून्य *' और 'static_cast' या तो काम नहीं करेगा, क्योंकि सदस्य फ़ंक्शन का सूचक सूचक नहीं है (हां, यह बहुत ही नामित है)। –

+0

स्थिर कलाकारों के संबंध में, मैं सोच रहा था कि मैं स्थिर सदस्य कार्यों को कार्यान्वित कर सकता हूं और स्पष्ट रूप से इस सूचक – NoahR

उत्तर

12

तो आप सभी की जरूरत त्रुटि संदेश की धड़कन है, तो कास्टिंग करना होगा:

class Derived : public Base 
{ 
    Derived() { 
     registerPrepFn(static_cast<PrepFn>(&Derived::derivedPrepFn)); 
    }; 

    void derivedPrepFn(int n) {}; 

} 

यह आम तौर पर कॉल एक Base* p साथ (प्रदान की यह वास्तव में एक व्युत्पन्न को इंगित करता है): (p->*registered)(0)

देखें एक कामकाजी उदाहरण के लिए http://ideone.com/BB9oy

+0

अच्छी तरह से, मैं सिर्फ त्रुटि संदेश को दबाना नहीं चाहता हूं। क्या यह कार्यात्मक होगा? – NoahR

+0

@NoahR: हाँ, यह काम करेगा (लेकिन बोल्डफेस में स्थिति से सावधान रहें) – jpalecek

+1

मानक इस तरह के रूपांतरण पर कहने के लिए है: "यदि कक्षा बी में मूल सदस्य है, या कक्षा का मूल या व्युत्पन्न वर्ग है मूल सदस्य, मूल सदस्य को सदस्य अंक के परिणामस्वरूप सूचक। अन्यथा, कास्ट का नतीजा अनिर्धारित है। " मुझे डर है कि इस तरह का कलाकार या तो ऐसा नहीं करेगा जो ओपी सबसे अच्छा चाहता है, या सबसे खराब मूल्य का उपयोग नहीं करता है। –

0

यह OOP के साथ अनुमति नहीं है। ऑब्जेक्ट निर्माण समय पर ऑब्जेक्ट की कक्षा को पॉलिमॉर्फ करके व्यवहारिक स्विचिंग को पूरा किया जाता है।

यदि आपको पोस्ट-ऑब्जेक्ट-निर्माण व्यवहार स्विचिंग की आवश्यकता है, तो आप गतिशील व्यवहार को पॉलीमोर्फिक वर्गों के दूसरे सेट पर दोबारा कर सकते हैं और सही व्यवहार के साथ कक्षा के उदाहरण के लिए "पॉइंटर" धारण कर सकते हैं। कृपया Google को "सजाया वर्ग" सॉफ़्टवेयर पैटर्न दें।

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