2009-06-13 41 views
38
class Foo { 
public: 
    Foo() { do_something = &Foo::func_x; } 

    int (Foo::*do_something)(int); // function pointer to class member function 

    void setFunc(bool e) { do_something = e ? &Foo::func_x : &Foo::func_y; } 

private: 
    int func_x(int m) { return m *= 5; } 
    int func_y(int n) { return n *= 6; } 
}; 

int 
main() 
{ 
    Foo f; 
    f.setFunc(false); 
    return (f.*do_something)(5); // <- Not ok. Compile error. 
} 

मैं कैसे प्राप्त कर सकते हैं करने के लिए इस काम करने के लिए?सी ++ समारोह सूचक (वर्ग के सदस्य) गैर स्थिर सदस्य समारोह

+1

'func_x' और 'func_y' स्थिर फ़ंक्शन नहीं हैं, भले ही उन्हें इस तरह चिह्नित नहीं किया गया हो? –

उत्तर

31

लाइन आप चाहते हैं

return (f.*f.do_something)(5); 

(मैं यह कोशिश की है कि संकलित) है से do_something value कहां प्राप्त करें। लेकिन हमें अभी भी ऑब्जेक्ट देने की ज़रूरत है जब हम फ़ंक्शन को कॉल करते हैं तो यह पॉइंटर होगा। यही कारण है कि हमें "f." उपसर्ग की आवश्यकता है।

+8

तकनीकी रूप से, "f.do_something" पॉइंटर लौटाता है, और "। *" ऑपरेटर क्लास पर पॉइंटर-टू-सदस्य फ़ंक्शन को कॉल करता है। –

+0

तो मुझे लगता है कि 'वापसी (एफ। * फू :: do_something) (5)' भी काम करना चाहिए। – ThomasMcLeod

+1

@ थॉमस एमसीएलओड यह नहीं करता है। –

0

कोशिश करें (एफ। * Do_something) (5);

"*f.do_something" सूचक ही --- को संदर्भित करता है "f" हमें बताता है -

35
class A{ 
    public: 
     typedef int (A::*method)(); 

     method p; 
     A(){ 
      p = &A::foo; 
      (this->*p)(); // <- trick 1, inner call 
     } 

     int foo(){ 
      printf("foo\n"); 
      return 0; 
     } 
    }; 

    void main() 
    { 
     A a; 
     (a.*a.p)(); // <- trick 2, outer call 
    } 
+3

+1 दो चाल के लिए +1 –

+0

तुडोक, दूसरी बार आपकी पोस्ट के माध्यम से जाने के बाद मुझे एहसास हुआ कि आपने सही उत्तर भी दिया है (चाल 2)। धन्यवाद। – Girish

+0

आपका कोड काम नहीं करता है। मैं प्रतिलिपि/पेस्ट और संकलन का प्रयास करें। test_function_pointer_2.C: कन्स्ट्रक्टर 'ए :: ए()': test_function_pointer_2.C: 7: त्रुटि: प्रकार 'int (ए ::)()' का तर्क 'int (ए :: *)() से मेल नहीं खाता है ' – user180574

-4

मुझे लगता है कि कक्षा के एक गैर स्थैतिक सदस्य को एक स्थिर सदस्य समारोह का उपयोग करके भी किया जा सकता है।

+1

यह संभव नहीं है। "कक्षा घोषणा में डेटा सदस्य को संशोधित करते समय, स्थिर कीवर्ड निर्दिष्ट करता है कि सदस्य की एक प्रति कक्षा के सभी उदाहरणों द्वारा साझा की जाती है। कक्षा घोषणा में सदस्य फ़ंक्शन को संशोधित करते समय, ** स्थिर कीवर्ड निर्दिष्ट करता है कि फ़ंक्शन एक्सेस करता है केवल स्थिर सदस्य **। " [एमएसडीएन संदर्भ] देखें (http://msdn.microsoft.com/en-us/library/s1sb61xd (v = vs.80) .aspx) – ForceMagic

+0

अच्छी तरह से, आप सभी उदाहरणों की एक सूची को कन्स्ट्रक्टर को खो सकते हैं और फिर कॉल कर सकते हैं यह सभी मामलों के लिए है, लेकिन मुझे लगता है कि कुछ हद तक विचार है: पी –

3
class A { 
    int var; 
    int var2; 
public: 
    void setVar(int v); 
    int getVar(); 
    void setVar2(int v); 
    int getVar2(); 
    typedef int (A::*_fVar)(); 
    _fVar fvar; 
    void setFvar(_fVar afvar) { fvar = afvar; } 
    void insideCall() { (this->*fvar)(); } 
}; 

void A::setVar(int v) 
{ 
    var = v; 
} 

int A::getVar() 
{ 
    std::cout << "A::getVar() is called. var = " << var << std::endl; 
    return var; 
} 

void A::setVar2(int v2) 
{ 
    var2 = v2; 
} 

int A::getVar2() 
{ 
    std::cout << "A::getVar2() is called. var2 = " << var2 << std::endl; 
    return var2; 
} 

int main() 
{ 
    A a; 
    a.setVar(3); 
    a.setVar2(5); 

// a.fvar = &A::getVar; 
    a.setFvar(&A::getVar); 
    (a.*a.fvar)(); 

    a.setFvar(&A::getVar2); 
    (a.*a.fvar)(); 

    a.setFvar(&A::getVar); 
    a.insideCall(); 

    a.setFvar(&A::getVar2); 
    a.insideCall(); 

    return 0; 
} 

मैंने निक डंडौलाकिस के जवाब को बढ़ाया। धन्यवाद।

मैंने एक फ़ंक्शन जोड़ा जो सदस्य फ़ंक्शन पॉइंटर को कक्षा के बाहर से सेट करता है। मैंने एक और फ़ंक्शन जोड़ा जिसे सदस्य फ़ंक्शन पॉइंटर के आंतरिक कॉल दिखाने के लिए बाहर से बुलाया जा सकता है।

+0

केवल कोड के ब्लॉक को पोस्ट करने के बजाय, कृपया * समझाएं * यह कोड समस्या को हल क्यों करता है। एक स्पष्टीकरण के बिना, यह एक जवाब नहीं है। –

+0

@MartijnPieters मैंने लिखा है कि यह निक डंडौलाकिस के उत्तर से बढ़ाया गया है। यह वहां समझाया गया था। मैं stackoverflow में नया हूँ शायद मुझे एक अलग तरीके से करने की जरूरत है। –

+0

ठीक है, आप समझा सकते हैं कि आपने क्या बदल दिया, उदाहरण के लिए, और क्यों। –

0
#include<iostream> 
using namespace std; 

class A { 

public: 
    void hello() 
    { 
     cout << "hello" << endl; 
    }; 

    int x = 0; 

}; 


void main(void) 
{ 

    //pointer 
    A * a = new A; 
    void(A::*pfun)() = &A::hello; 
    int A::*v1 = &A::x; 

    (a->*pfun)(); 
    a->*v1 = 100; 
    cout << a->*v1 << endl << endl; 

    //----------------------------- 
    A b; 
    void(A::*fun)() = &A::hello; 
    int A::*v2 = &A::x; 

    (b.*fun)(); 
    b.*v2 = 200; 
    cout << b.*v2 << endl; 

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