2009-01-27 9 views
6

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

class Base 
{ 
public: 
    BaseClass(); 
    virtual ~BaseClass(); 
}; 

class Derived : public Base 
{ 
public: 
    // assign strFunction to the function pointer passed in 
    Derived(string (*funPtr)(int)) : strFunction(funPtr); 
    ~Derived(); 

private: 
    // pointer to the function that is passed in 
    string (*strFunction)(int value); 
}; 

class MainClass 
{ 
public: 
    MainClass() 
    { 
     // allocate a new Derived class and pass it a pointer to myFunction 
     Base* myClass = new Derived(&MainClass::myFunction);  
    } 

    string myFunction(int value) 
    { 
     // return a string 
    } 
}; 

मुझे इस कोड को संकलित करने का प्रयास करें, त्रुटि मैं मिलता है

error: no matching function for call to 'Derived::Derived(string (MainClass::*)(int))'

द्वारा

note: candidates are: Derived::Derived(string (*)(int))

किसी भी विचार का पालन किया है कि मैं क्या हो सकता है गलत कर रहे हो?

उत्तर

8

आपका वाक्यविन्यास सी शैली फ़ंक्शन पॉइंटर के लिए सही है। यह इस में बदलें:

Derived(string (MainClass::*funPtr)(int)) : strFunction(funPtr) {} 

और

string (MainClass::*strFunction)(int value); 

strFunction कॉल करने के लिए याद है, आप एक MainClass वस्तु का एक उदाहरण की आवश्यकता होगी। अक्सर मुझे टाइपपीफ का उपयोग करने में उपयोगी लगता है।

typedef string (MainClass::*func_t)(int); 
func_t strFunction; 

और

Derived(func_t funPtr) : strFunction(funPtr) {} 
+0

और कक्षाओं को डीकॉप्लेड करने के बारे में क्या है और आप 'MainClass :: * funPtr' निर्दिष्ट नहीं कर सकते हैं? – fduff

+0

फिर मैं पैरामीटर को 'बूस्ट :: फ़ंक्शन ' पैरामीटर बनाने और 'बूस्ट :: बाइंड' –

+0

टीएक्स के साथ फ़ंक्शन को पास करने जैसी सामान्य लाइब्रेरी का उपयोग करने की अनुशंसा करता हूं लेकिन गैर-बूस्ट प्रोजेक्ट के बारे में क्या? 'std :: function()' और 'std :: bind()' केवल C++ 11 में उपलब्ध हैं जो हमारे पास नहीं है। – fduff

0

ऑब्जेक्ट विधियों में एक छिपी "यह" तर्क है। यदि आप किसी अन्य वर्ग को विधि पारित करते हैं, तो "इस" तर्क में क्या भर जाता है? आप इसे स्थैतिक (कक्षा) विधियों के साथ करने में सक्षम हो सकते हैं।

2

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

आप एक कन्स्ट्रक्टर को एक विधि-सूचक पास करने का प्रयास कर रहे हैं जो फ़ंक्शन-पॉइंटर लेता है। जो काम नहीं करेगा।

+0

यह समझ में आता है। – Chris

4

हां, &MainClass::myFunction का प्रकार एक सूचक-से-सदस्य प्रकार है जबकि string(*)(int) एक पॉइंटर-टू-फ़ंक्शन प्रकार है। वे संगत नहीं हैं क्योंकि आपको किसी क्लास इंस्टेंस में संदर्भ या पॉइंटर का उपयोग करना है और एक पॉइंटर-टू-सदस्य का उपयोग करने के लिए। * या -> * ऑपरेटर का उपयोग करना है, जबकि किसी फ़ंक्शन के लिए पॉइंटर क्लास से जुड़ा नहीं है और कर सकता है सीधे कहा जा सकता है।

4

आप वर्ग MainClass के एक सदस्य के कार्य करने के लिए एक सूचक पारित करने के लिए कोशिश कर रहे हैं, लेकिन एक साधारण समारोह के लिए सूचक, यानी गैर-सदस्य, समारोह की उम्मीद है। एक अच्छा सारांश here

अंतर महत्वपूर्ण है क्योंकि सदस्य फ़ंक्शंस में एक अतिरिक्त अतिरिक्त पैरामीटर होता है जो फ़ंक्शन को "यह" पॉइंटर फ़ंक्शन को लागू करने के लिए बताता है। तो सूचक प्रकार अदला-बदले नहीं हैं।

0

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

2

एक और वाक्य रचना मुद्दा:


    // assign strFunction to the function pointer passed in 
    Derived(string (*funPtr)(int)) : strFunction(funPtr); 

की जगह के लिए:

class Derived: public Base 
{ 
    public: 
    typedef std::tr1::function<string(int)> StringFunc; 

    Derived(StringFunc); 

    ... 

    private: 
    StringFunc strFunction; 
} 

:


    // assign strFunction to the function pointer passed in 
    Derived(string (*funPtr)(int)) : strFunction(funPtr) {}; 
1

आप std::tr1::bind और std::tr1::function इस (untested) कोड के लिए इसी तरह का उपयोग कर में देखना चाहते हो सकता है और मेनक्लास कन्स्ट्रक्टर में:

myBase = new Derived(std::tr1::bind(&MainClass::myFunction, *this, _1); 

बाइंड फ़ंक्शन मूल रूप से किसी विशेष ऑब्जेक्ट में सदस्य फ़ंक्शन को बांधता है। जो संकलक द्वारा डाला गया इस सूचक का ख्याल रखता है।