2009-12-23 12 views
5

मैं विधि void run(string method) जो कि कक्षा में विधि चलाने होता है करने के लिए कोशिश कर रहा हूँ। उदाहरण के लिए:मैं केवल अपना नाम दिए गए तरीके को कैसे कॉल कर सकता हूं?

class Foo { 
    public: 
    void run(string method) { 
     // this method calls method *method* from this class 
    } 
    void bar() { 
     printf("Function bar\n"); 
    } 
    void foo2() { 
     printf("Function foo2\n"); 
    } 
} 

Foo foo; 

int main(void) { 
    foo.run("bar"); 
    foo.run("foo2"); 
} 

इस प्रिंट होगा:

Function bar 
Function foo2 

धन्यवाद! :)

+1

आप पूरा करने के लिए कोशिश कर रहे हैं? –

उत्तर

15

आप std::map बना सकते हैं जो सदस्य फ़ंक्शन पॉइंटर्स के तारों को मानचित्र करता है, जब तक कि आप जिन सभी कार्यों को कॉल करना चाहते हैं, वे समान हस्ताक्षर हैं।

std::map<std::string, void(Foo::*)()> function_map; 
+2

अन्यथा, 'अगर() {} else if() {} else if() {} else {}' अभी भी यहाँ ;-) –

+2

है अगर मैं इस समाधान के लिए जाने के लिए थे, हालांकि, मैं इसे एक स्थिर बनाने चाहते हैं नक्शा - रनटाइम तक कभी भी स्थगित न करें जो आप संकलन समय पर कर सकते हैं। –

2

आप मानचित्र फ़ंक्शन का नाम होने के प्रमुख के साथ सदस्य समारोह संकेत का एक नक्शा बना सकते हैं,:

मानचित्र की तरह घोषित किया जाएगा। सदस्य कार्यों के लिए पॉइंटर्स हालांकि काम करने के लिए थोड़ा मुश्किल हैं।

http://www.parashift.com/c++-faq-lite/pointers-to-members.html

आसान तरीका है अपने run समारोह उचित फ़ंक्शन को कॉल करने में अगर-तो-और कुछ ब्लॉक के एक गुच्छा करना है।

6

नक्शा समाधान पहले से ही कार्यों का तय सूचियों के लिए काम करेगा उल्लेख किया है, लेकिन मुझे नहीं लगता कि सी में सामान्य रूप में इस तरह आत्मनिरीक्षण करने ++ एक तरीका है। यही कारण है कि आप एक समारोह void perform(string methodName) जो कहता है नहीं हो सकता है, "मैं एक विधि methodName कहा जाता है? यदि हां, तो यह कहते हैं।"

+0

हां, सी ++ इस संबंध में जावा की तरह बिल्कुल नहीं है। – Omnifarious

+0

... भी ऑब्जेक्टिव-सी, अजगर, पर्ल, जावास्क्रिप्ट, रूबी, सी # ... – benzado

+0

@benzado पसंद नहीं: ऑब्जेक्टिव-सी पूरी तरह से अलग यदि आप एक संदेश भेज रहे हैं है। अगर ऑब्जेक्ट जानता है कि संदेश पर प्रतिक्रिया कैसे करें तो यह कोड निष्पादित करेगा। पायथन/पर्ल/जावास्क्रिप्ट: सभी ऑब्जेक्ट्स केवल नक्शे हैं इसलिए विधियां केवल मूल्य के रूप में संलग्न वस्तुएं हैं। सी # और जावा उस प्रकार में भिन्न हैं आत्मनिरीक्षण (एकेए प्रतिबिंब) इस प्रकार आपको नाम से विधियों को खोजने की अनुमति देता है और फिर उन्हें कॉल करता है। –

1

जैसा कि अन्य पोस्टर ने कहा है, आपको इसे सी ++ में हाथ से करने की ज़रूरत है, क्योंकि भाषा में Reflection अंतर्निहित नहीं है।

बोली की तरह सी # और जावा इस तो यह क्या आप के लिए यह आवश्यकता होगी, कर रहे हैं पर निर्भर करता है, भाषा की अपनी पसंद पर पुनर्विचार लायक हो सकता है में निर्माण किया है।

-3

आप RTTI या नक्शे के कुछ प्रकार के बिना यह नहीं कर सकते। या फिर इस तरह एक समाधान:

 
class Foo { 
    public: 
    void run(string method) { 
     bar(method); 
     foo2(method); 
    // ... more methods here 
    } 
    void bar(string method) { 
     if (method != "bar") return; 
     printf("Function bar\n"); 
    } 
    void foo2(string method) { 
     if (method != "foo2") return; 
     printf("Function foo2\n"); 
    } 
} 

Foo foo; 

int main(void) { 
    foo.run('bar'); 
    foo.run('foo2'); 
}

यह आप एक ही परिणाम आप

+2

आपका सुझाया गया समाधान बस भयानक है। यह अक्षम है, क्योंकि एन विधियों के लिए 'रन' के लिए प्रत्येक कॉल के परिणामस्वरूप एन विधि कॉल चाहे कोई फर्क नहीं पड़ता। यह भी असंभव है, क्योंकि किसी विधि को नाम मैप करने के लिए तर्क विधियों के बीच वितरित किया जाता है। – benzado

9

चाहता था के रूप में अन्य लोगों ने बताया है, सी ++ बॉक्स से बाहर प्रतिबिंब इस तरह का काम नहीं करता दे देंगे (और बाधाओं कि कर रहे हैं शायद यह नहीं है कि आप क्या करना चाहते हैं।)

लेकिन मैं उल्लेख करूंगा कि वहां कुछ प्रीप्रोसेसर मौजूद हैं जो कक्षा प्रकारों और विधियों के उप-समूह के लिए इस कार्यक्षमता को लागू करते हैं। क्यूटी का मुखौटा इसका एक उदाहरण है, और यह सिग्नल/स्लॉट यांत्रिकी का हिस्सा है। सूचना method() और methodCount()QMetaObject पर ...

तरह से क्यूटी यह आपके निर्माण प्रक्रिया टेबल बनाता है और उन्हें अपने कोड के बाकी के साथ में संकलित है कि में एक उपकरण के इंजेक्शन लगाने के द्वारा है नहीं करता है। यह सब सामान है जो आप हाथ से लिखे थे - एक भाषा सुविधा नहीं।

3

हालांकि पिछले जवाब अपने समाधान के लिए कर रहे हैं, अपने समाधान आपकी समस्या के लिए सही तरह नहीं दिखता है।

मेरे पास दो सुझाव हैं: 1) बेहतर सार आधार वर्ग बनाएं या 2) मज़दूरों के लिए बेस क्लास का उपयोग करें (फ़ंक्शन ऑब्जेक्ट्स)।चलो और अधिक विस्तार में उनकी ओर देखो ...

एक प्रोसेसर के अनुदेश सेट का अनुकरण की एक परियोजना को देखते हुए, हम साथ निष्पादन अनुकरण कर सकते हैं:

struct Instruction_Interface 
{ 
    virtual void execute(void) = 0; 
}; 

typedef std::vector<Instruction_Interface *> Instruction_Container; 

//... 
Instruction_Container::iterator iter; 
Instruction_Container program_instructions; 
//... 
for (iter = program_instructions.begin(); 
    iter != program_instructions.end(); 
    ++iter) 
{ 
    (*iter)->execute(); // Execute the instruction; 
} 

यह प्रत्येक अनुदेश के execute विधि के फोन करने की अनुमति देता है, की परवाह किए बिना निर्देश की तरह। कोई इंटरफ़ेस में और विधियां जोड़ सकता है; इस उदाहरण में कोई "toString" जोड़ सकता है जो निर्देश को पाठ में परिवर्तित करेगा।

Idea 2: Functors 

कार्यों आप उपयोग करना चाहते के लिए एक आधार वर्ग या इंटरफ़ेस स्थापित करना। उन्हें एक कंटेनर में रखें और कंटेनर पर फिर से भरें। यात्रा सशर्त भी हो सकता है:

struct Functor_Interface 
{ 
    virtual std::string get_name(void) const = 0; 
    virtual void   execute(void) = 0; 
    virtual void   execute_if_name(const std::string& name) 
    { if (name == get_name()) 
    { 
     execute(); 
    } 
    } 
}; 

typedef std::vector<Functor_Interface *> Functor_Container; 
//... 
Functor_Container the_functors; 
//... 
Functor_Container::iterator iter; 
for (iter = the_functors.begin(); 
    iter != the_functors.end(); 
    ++iter) 
{ 
    (*iter)->execute_if_name("loader"); // Execute the functor if it is a *loader*. 
    (*iter)->execute_if_name("math"); 
} 

सारांश में, अपने डिजाइन पर लगता है कि अगर वहाँ एक बेहतर प्रक्रिया है कि समारोह के नाम की आवश्यकता नहीं है है, लेकिन इसके बजाय या तो समारोह निष्पादित करने के लिए तय कर सकते हैं या सामान्य रूप से अंधा कार्यान्वित को देखने के लिए तरीकों।

1

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

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

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