C++ calling a function from a vector of function pointers inside a class where the function definition is in main

只谈情不闲聊 提交于 2019-12-30 04:22:10

问题


Alright, in my main i have:

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
}

and in the class:

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])();;
}

I'm sort of new-ish to pointers, but I read over my c++ books, googled, ext. and this seems correct, compiles, runs but when I call "actionWithDiffrentOutcomes()" I get an access violation. I'm not sure what to do. it seems correct, but something is obviously wrong. So how can I call a function from within a class when the definition is in another?

I'm doing it this way because i cannot hard-code every option into a switch statement.


回答1:


Your code is almost correct. Your vector is mistakenly holding pointers to pointers to functions rather than simply pointers to functions. addThingy is adding the address of the function pointer in to the vector, but that pointer goes out of scope in the next line.

Change your code as follows:

//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);
}

Also, you have a lot of syntax errors in the rest of the code which should stop the code from even compiling.




回答2:


The problem is here:

vectoroffunctions.push_back(&function);

You're adding address of the local variable. The local variable gets destroyed once you return from the function. The address which the vector stores points to a destroyed object which is why you get "access violation" error at runtime.

To fix this, do this:

First change this

std::vector<void (**)()> vectoroffunctions;

to this:

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

which is practically same as:

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

Now do this:

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

To make it more flexible, you could use template along with std::function as:

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;
};

Now you can use it to store functions as well as 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();

Output (Online Demo):

myfunction
myfunctor

Hope that helps.




回答3:


Function pointers are much more legible with typedefs:

typedef void (*RequiredFunction)();

Then you can declare addThingy() like this:

    void addThingy(RequiredFunction function);

And vectoroffunctions like so:

    std::vector<RequiredFunction> vectoroffunctions;

The definition of addThingy will be:

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

And your main() would look more like:

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

Far fewer *s and &s with which to make mistakes!



来源:https://stackoverflow.com/questions/15128444/c-calling-a-function-from-a-vector-of-function-pointers-inside-a-class-where-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!