2009-02-05 11 views
20
struct TimerEvent 
{ 
    event Event; 
    timeval TimeOut; 
    static void HandleTimer(int Fd, short Event, void *Arg); 
}; 

हैंडल टिमर स्थिर होने की आवश्यकता है क्योंकि मैं इसे सी लाइब्रेरी (libevent) में भेज रहा हूं।व्युत्पन्न वर्ग बेस क्लास से स्थिर कार्य कैसे प्राप्त कर सकता है?

मैं इस कक्षा से उत्तराधिकारी बनना चाहता हूं। यह कैसे किया जा सकता है?

धन्यवाद।

+0

बस उत्तराधिकारी और इसे काम करना चाहिए। क्या आपको इसके साथ कोई विशेष समस्या है? – jpalecek

+0

मैं उपर्युक्त टिप्पणी से सहमत हूं, मुझे प्रश्न समझ में नहीं आता है। –

+0

मैं उपर्युक्त टिप्पणी तीसरा। :) –

उत्तर

33

आप आसानी से उस वर्ग से विरासत कर सकते हैं:

class Derived: public TimerEvent { 
    ... 
}; 

लेकिन, आप अपने उपवर्ग में HandleTimer ओवरराइड नहीं कर सकते हैं और इस काम करने की उम्मीद:

TimerEvent *e = new Derived(); 
e->HandleTimer(); 

इसका कारण यह है स्थिर तरीकों डॉन है ' vtable में प्रवेश नहीं है, और इस प्रकार वर्चुअल नहीं हो सकता है। आप फिर भी उपयोग कर सकते हैं "शून्य * Arg" की तरह अपने उदाहरण के लिए सूचक ... कुछ पारित करने के लिए:

struct TimerEvent { 
    virtual void handle(int fd, short event) = 0; 

    static void HandleTimer(int fd, short event, void *arg) { 
     ((TimerEvent *) arg)->handle(fd, event); 
    } 
}; 

class Derived: public TimerEvent { 
    virtual void handle(int fd, short event) { 
     // whatever 
    } 
}; 

इस तरह, HandleTimer अभी भी सी कार्यों से इस्तेमाल किया जा सकता है, बस हमेशा पारित "यह सुनिश्चित कर लें असली "ऑब्जेक्ट" शून्य * Arg "के रूप में।

+0

इस तरह की स्थैतिक उपयोग की आवश्यकता नहीं है, मैं इसका उपयोग करूंगा: व्युत्पन्न टी; t.handle (...); – raidsan

0

आपके प्रश्न में आपको कुछ संघर्ष हुआ है। जब आप &TimerEvent::TimerHandler को सी लाइब्रेरी में पास करते हैं, तो आप वही करते हैं। यदि आप चाहें तो आप &DerivedTimerEvent::TimerHandler पास कर सकते थे। लेकिन आप &TimerEvent::TimerHandler पास नहीं कर सकते हैं और सी लाइब्रेरी (!) की अपेक्षा करने के लिए वास्तव में &DerivedTimerEvent::TimerHandler का अनुमान लगा सकते हैं।

+1

इसकी 'स्थैतिक' के बाद से, मैं अपेक्षा करता हूं कि संकलक सी पुस्तकालय तक पहुंचने से पहले लंबे समय तक संकल्प को हल करे। –

8

कुछ विस्तार करने के लिए लक्षण पैटर्न आपको स्थिर तरीकों का वारिस और फिर से परिभाषित करने देता है।

एक आधार वर्ग के साथ सबसे पहले शुरू:

struct base { 
    static void talk() { std::cout << "hello" << std::endl; } 
    static void shout() { std::cout << "HELLO !!" << std::endl; } 
}; 

तो यह निकाले जाते हैं और फिर से परिभाषित कुछ तरीके:

struct derived: public base { 
    static void talk() { std::cout << "goodbye" << std::endl; } 
}; 

और अब एक लक्षण वर्ग के माध्यम से तरीकों फोन:

template < class T > 
struct talker_traits { 
    static void talk() { T::talk(); } 
    static void shout() { T::shout(); } 
}; 

talker_traits<base>::talk()  // prints "hello" 
talker_traits<base>::shout() // prints "HELLO !!" 

talker_traits<derived>::talk() // prints "goodbye" 
talker_traits<derived>::shout() // prints "HELLO !!" 

ideone demo

गुण वर्ग आपको derived::talk के साथ base::talk "ओवरराइडिंग" करते समय स्थैतिक विधि base::shout का उपयोग करने देता है। फिर भी, वास्तविक विरासत के साथ कई अंतर हैं:

  • समारोह कॉल करने के लिए संकलन समय पर हल हो गई है
  • बच्चे विधि माता पिता एक

यह साथ काम करता है के रूप में ही हस्ताक्षर नहीं की जरूरत है स्थैतिक फ़ील्ड और टाइपपीफ भी, सबसे अच्छा उदाहरण std::iterator_traits है।

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