2013-02-28 12 views
10

ठीक है अंदर समारोह संकेत का एक वेक्टर से एक समारोह बुला अपने मुख्य में मेरे पास है:सी ++, एक वर्ग जहां समारोह परिभाषा मुख्य

void somefunction(); 
int main() 
{ 
    //bla bla bla 
    SomeClass myclass = SomeClass(); 
    void(*pointerfunc)() = somefunction; 
    myclass.addThingy(pointerfunc); 

    //then later i do 
    myclass.actionWithDiffrentOutcomes(); 
} 

void somefunction() 
{ 
    //some code 
} 

और कक्षा में:

class SomeClass() 
{ 
    public: 
     void addThingy(void (*function)()); 
     void actionWithDiffrentOutcomes(); 
    private: 
     std::vector<void (**)()> vectoroffunctions; 
} 
SomeClass::addThingy(void (*function)()) 
{ 
    vectoroffunctions.push_back(&function); 
} 
SomeClass::actionWithDiffrentOutcomes() 
{ 
    (*vectoroffunctions[0])();; 
} 

मैं पॉइंटर्स के लिए नया-आईएसएच हूं, लेकिन मैंने अपनी सी ++ किताबें, गुगल, एक्सटी पर पढ़ा। और यह सही लगता है, संकलित करता है, चलता है लेकिन जब मैं "actionWithDiffrentOutcomes()" को कॉल करता हूं तो मुझे एक एक्सेस उल्लंघन मिलता है। मुझे यकीन नहीं है कि क्या करना है। यह सही लगता है, लेकिन कुछ स्पष्ट रूप से गलत है। तो जब परिभाषा किसी दूसरे में होती है तो मैं कक्षा के भीतर से एक फ़ंक्शन कैसे कॉल कर सकता हूं?

मैं इसे इस तरह से कर रहा हूं क्योंकि मैं स्विच विकल्प में हर विकल्प को हार्ड-कोड नहीं कर सकता।

+0

आपका नमूना कोड संकलित नहीं करता है; क्या आप सिंटैक्स को दोबारा जांच सकते हैं और अपना प्रश्न संपादित कर सकते हैं? – congusbongus

+0

यह कोड संकलित नहीं करेगा। कृपया एक [लघु, स्वयं युक्त, सही (संकलित), उदाहरण] प्रदान करें (http://sscce.org/)। – Johnsyweb

उत्तर

12

आपका कोड लगभग सही है। आपका वेक्टर गलती से पॉइंटर्स को पॉइंटर्स को फ़ंक्शंस के बजाय पॉइंटर्स की बजाय कार्यों में रखता है। addThingy पॉइंटर का पता vector में जोड़ रहा है, लेकिन यह सूचक अगले पंक्ति में दायरे से बाहर हो जाता है।

//Store pointers to functions, rather than 
//pointers to pointers to functions 
std::vector<void (*)()> vectoroffunctions; 

SomeClass::addThingy(void (*function)()) 
{ 
    //Don't take the address of the address: 
    vectoroffunctions.push_back(function); 
} 

इसके अलावा, आप कोड जो भी संकलन से कोड बंद कर देना चाहिए के बाकी हिस्सों में वाक्यविन्यास त्रुटियों की एक बहुत कुछ है:

इस प्रकार

अपने कोड में परिवर्तित करें।

+0

आह धन्यवाद, जो अधिक समझ में आता है। इसके अलावा, वाक्यविन्यास के बारे में खेद है, मैंने इसे पोस्ट करने के लिए इसे एनपी ++ में कॉपी किया है, फिर मेरा पूरा कार्यक्रम पोस्ट करें। –

5

समस्या यहाँ है:

vectoroffunctions.push_back(&function); 

आप स्थानीय चर का पता जोड़ रहे। एक बार जब आप फ़ंक्शन से वापस आते हैं तो स्थानीय चर नष्ट हो जाता है। वह पता जो वेक्टर स्टोर्स एक नष्ट ऑब्जेक्ट को इंगित करता है, यही कारण है कि आपको रनटाइम पर "एक्सेस उल्लंघन" त्रुटि मिलती है।

इसे ठीक करने के लिए इस कार्य करें:

पहले परिवर्तन इस

std::vector<void (**)()> vectoroffunctions; 
इस के लिए

:

std::vector<void (*)()> _functions; //vector of function-pointer-type 
            //I changed the name also! 

जो व्यावहारिक रूप से एक ही है के रूप में:

std::vector<void()> _functions; //vector of function-type 

अब करना यह:

_functions.push_back(function); //add copy! 

यह अधिक लचीला बनाने के लिए, आप के साथ टेम्पलेट का उपयोग कर सकते std::function के रूप में:

class A 
{ 
    public: 
     template<typename Function> 
     void add(Function && fn) 
     { 
      _functions.push_back(std::forward<Function>(fn)); 
     } 
     void invoke_all() 
     { 
      for(auto && fn : _functions) 
       fn(); 
     } 
    private: 
     std::vector<std::function<void()>> _functions; 
}; 

अब आप कार्यों के साथ-साथ functors स्टोर करने के लिए उपयोग कर सकते हैं:

void myfunction() { std::cout << "myfunction" << std::endl ; } 

struct myfunctor 
{ 
     void operator()() { std::cout << "myfunctor" << std::endl ; } 
}; 

A a; 
a.add(myfunction); //add function 
a.add(myfunctor()); //add functor! 
a.invoke_all(); 

आउटपुट (Online Demo):

myfunction 
myfunctor 

आशा है कि मदद करता है।

+0

परिवर्तनीय तर्क के साथ कार्यों के लिए कोई सुरुचिपूर्ण समाधान? –

+0

@ एसआईडी: उपयोग केस क्या है? – Nawaz

1

समारोह संकेत typedefs साथ और अधिक सुपाठ्य हैं:

void addThingy(RequiredFunction function); 

और vectoroffunctions तो जैसे:

std::vector<RequiredFunction> vectoroffunctions; 

की परिभाषा

typedef void (*RequiredFunction)(); 

तो फिर तुम इस तरह addThingy() घोषणा कर सकते हैं addThingy होगा:

void SomeClass::addThingy(RequiredFunction function) 
{ 
    vectoroffunctions.push_back(function); 
} 

और अपने main() लगेगा अधिक की तरह:

int main() 
{ 
    SomeClass sc; 
    RequiredFunction pointerfunc = somefunction; 
    sc.addThingy(pointerfunc); 
    sc.actionWithDiffrentOutcomes(); 
} 

सुदूर कम * और जिसके साथ गलतियाँ करने के लिए & रों!

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