2009-03-23 15 views
5

निम्न कोड पर विचार करें:क्या सी ++ में विधि कॉल प्रेषक बनाना संभव है?

struct X { 
    void MethodX() { 
    ... 
    } 
}; 

struct Y { 
    void MethodY() { 
    ... 
    } 
}; 

void test() { 
    X x; 
    Y y; 
    Dispatcher d; 
    d.Register("x", x, &X::MethodX); 
    d.Register("y", y, &Y::MethodY); 
    d.Call("x"); 
    d.Call("y"); 
} 

प्रश्न यह है कि प्रेषक को कैसे कार्यान्वित किया जाए। मुझे कोई फर्क नहीं पड़ता कि एक्स और वाई कुछ से विरासत में हो सकते हैं, लेकिन डिस्पैचर को आगे के ग्राहकों को अनुमति देना चाहिए (न केवल एक्स और वाई)। और यदि संभव हो तो मैं शून्य * पॉइंटर्स से बचना चाहता हूं :)

+0

क्या आपके पास बूस्ट लाइब्रेरी तक पहुंच है? –

+0

क्या आप कृपया स्पष्टीकरण दे सकते हैं "समस्या पॉइंटर्स या फ़ैक्टर को रखते हुए डेटा संरचना का प्रकार है।" –

+0

मैं इसे std :: tr1 :: mem_fun टेम्पलेट के साथ कार्यान्वित करने का प्रयास कर रहा था। लेकिन परिणाम का प्रकार पैरामीटर के प्रकार के अंदर था। तो मैं इसे एक विषम वेक्टर नहीं बना सका। –

उत्तर

5

boost::function पर एक नज़र डालें, यह ऐसा करता है।

+0

मैं समस्या का समाधान नहीं करता हूं। अद्यतन प्रश्न पर एक नज़र डालें। –

+0

शायद यह करता है। मैं जांच कर रहा हूं :) –

1

मेरे पास एक समान उत्तर here है, लेकिन माइकोला का उत्तर आपको जो चाहिए उसे करीब है।

1

इस पत्र पर एक नज़र डालें:

http://www.oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/functor/functor.html

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

2

बढ़ावा देने से बचने और अपने आप को कार्यान्वित करने के लिए पुस्तक http://en.wikipedia.org/wiki/Modern_C%2B%2B_Design

वहाँ एक लोकी कैसे बनाने के लिए एक अच्छा विवरण के साथ पुस्तक में वर्णित पुस्तकालय है पर एक नज़र डालें अपनी खुद की अपनी जरूरत functor के लिए बहुत चालाक।

class Dispather 
{ 
public: 
    typedef boost::function< void (void) > FunctionT; 

    void Register(const std::string& name, FunctionT function) 
    { 
     registered_[ name ] = function; 
    } 

    void Call(const std::string& name) 
    { 
     RegisterdFunctionsT::const_iterator it = 
      registered_.find(name); 

     if (it == registered_.end()) 
      throw std::logic_error("Function is not registered"); 

     (it->second)(); 
    } 

private: 
    typedef std::map< std::string, FunctionT > RegisterdFunctionsT; 
    RegisterdFunctionsT registered_; 

}; 

int main() 
{ 
    X x; 
    Y y; 

    Dispather d; 
    d.Register("x", boost::bind(&X::MethodX, &x)); 
    d.Register("y", boost::bind(&Y::MethodY, &y)); 

    d.Call("x"); 
    d.Call("y"); 

    return 0; 
} 
+0

यह बहुत अच्छा लग रहा है। यह फ़ंक्शन टी में टाइपफ़ोफ़ (& X :: MethodX) कैसे डाला जाता है? मैं इसे अपने आप कैसे कार्यान्वित कर सकता हूं और बढ़ावा के उपयोग से बच सकता हूं? –

+0

बढ़ावा उपयोग से बचने के लिए ... और फिर आप boost :: function का उपयोग कर रहे हैं? –

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