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.
Using a pointer-to-member-function to call a function Calling the member function on an object using a pointer-to-member-function result = (object. *pointer_name)(arguments); or calling with a pointer to the object result = (object_ptr->*pointer_name)(arguments);
A pointer to a function points to the address of the executable code of the function. You can use pointers to call functions and to pass functions as arguments to other functions.
the constructor is the first function which get called. and we can access the this pointer via constructor for the first time. if we are able to get the this pointer before constructor call (may be via malloc which will not call constructor at all), we can call member function even before constructor call.
The pointer to member operators . * and ->* are used to bind a pointer to a member of a specific class object.
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.
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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With