I have a struct Game with a function pointer called onBegin
struct Game {
// ...
void (*onBegin)(Game&);
// ...
};
What I am attempting to do is allow the user to create their own onBegin function, in which they could say
void CustomFunc(Game& g) {
// Do something
}
Game g = Game();
g.onBegin = *CustomFunc;
What I am attempting to do is make a function and then set the pointer onBegin to point at that default function.
struct Game {
public:
void (*onBegin)(Game&);
private:
void defualtOnBegin(Game&);
};
// In the constructor
Game::Game() {
// ...
this->onBegin = this->defaultOnBegin; // This is what is giving me the error
}
I receive the error: a pointer to a bound function may only be used to call the function and do not know what is wrong here.
What I am attempting to do is allow the user to create their own onBegin function...
You could achieve that in different ways, however as you want to go for a function-pointer approach, you might want to utilize std::function like:
#include <iostream>
#include <functional>
struct Game {
public:
Game(std::function<void(Game&)> customOnBeginFnc = nullptr) {
if(customOnBeginFnc) {
customOnBeginFnc(*this);
} else {
defaultOnBegin(*this);
}
}
private:
void defaultOnBegin(Game&) {
std::cout << "Default 'onBegin'\n";
}
};
void customOnBegin(Game&) {
std::cout << "Custom 'onBegin'\n";
}
int main() {
{
std::cout << "Starting a 'default' game...\n";
Game g;
}
{
std::cout << "Starting a 'customized' game...\n";
Game g(customOnBegin);
}
}
Run it here.
The advantage of that approach would be that you are not limited to free functions but you could also bind a member function to it via a lambda or std::bind.
Related
Within JavaScript, you can pull off something like this:
function bunny() { alert("The bunny jumped."); }
var oldBunny = bunny;
function bunny() {
oldBunny();
alert("The bunny also ran.");
}
bunny(); // The bunny Jumped. The bunny also ran.
As one can see, the old "bunny" function had code appended to it by copying to a variable, then recreating the function with the same name. The copy of the original function runs, and the new code also runs.
I wish to replicate a similar mechanic in C++.
Now before you have a meltdown and start explaining the differences between static and dynamic languages, I get it. I'm not looking for something identical to what's provided, but I do desire something similar.
Furthermore, I'm not trying to do this to modify existing code; I wish to format my own source code to allow such a mechanic for other users to take advantage of.
One of the first ideas I had was to perhaps setup various macros within the code that could later be modified by other files.
Another idea would be to create a Signal and Slots system like in QT. Though I have no clue how to do such a thing myself.
Thank you for reading; I hope you have some suggestions.
Well, if you recognize which feature of JavaScript functions makes this possible, it's not too hard to do the same in C++. In JavaScript functions also have closures, which regular function in C++ don't have. But C++ lambdas are of a closure type. And if one defines bunny to be something which can both hold an object of a closure type, and be reassigned, you're all set.
The C++ standard library offers a nice default choice for this, in the form of std::function. We can just re-write your original JavaScript as follows:
std::function<void()> bunny = [] {
std::cout << "The bunny jumped.\n";
};
auto oldBunny = std::move(bunny);
bunny = [oldBunny] {
oldBunny();
std::cout << "The bunny also ran.\n";
};
bunny();
You can use functors.
#include <iostream>
#include <string>
class Base
{
public:
virtual std::string operator ()()
{
return "Base call";
}
virtual ~Base() {}
};
class Derived : public Base
{
public:
virtual std::string operator()()
{
return "Wrapper: " + Base::operator()();
}
};
int main()
{
Base* pFun = new Base;
std::cout << "Now check Base: " << (*pFun)() << std::endl;
delete pFun;
pFun = new Derived;
std::cout << "Now check Derived: " << (*pFun)() << std::endl;
return 0;
}
Assuming the goal is to allow the calling code to extend the program's functionality beyond what the initial code provided, I might use a user-updatable array of functor-objects, something like this:
#include <iostream>
#include <memory>
class Function
{
public:
virtual void Call() = 0;
};
typedef std::shared_ptr<Function> FunctionSharedPointer;
class OldBunny : public Function
{
public:
virtual void Call()
{
std::cout << "The bunny jumped." << std::endl;
}
};
class NewBunny : public Function
{
public:
NewBunny(FunctionSharedPointer oldFunction) : _oldFunction(oldFunction) {/* empty */}
virtual void Call()
{
_oldFunction->Call();
std::cout << "The bunny also ran." << std::endl;
}
private:
FunctionSharedPointer _oldFunction;
};
enum {
FUNCTION_BUNNY,
// other functions could be declared here later...
NUM_FUNCTIONS
};
// Our table of functions that the user can Call() if he wants to
static FunctionSharedPointer _functionTable[NUM_FUNCTIONS];
// Wrapper function, just to keep users from accessing our table directly,
// in case we ever want to change it to something else
void CallFunction(int whichFunction)
{
_functionTable[whichFunction]->Call();
}
// Another wrapper function
void SetFunction(int whichFunction, FunctionSharedPointer newFunctionDefinition)
{
_functionTable[whichFunction] = newFunctionDefinition;
}
// And another
FunctionSharedPointer GetFunction(int whichFunction)
{
return _functionTable[whichFunction];
}
int main(int argc, char ** argv)
{
// Our default function values get set here
SetFunction(FUNCTION_BUNNY, std::make_shared<OldBunny>());
std::cout << "before:" << std::endl;
CallFunction(FUNCTION_BUNNY);
// Now let's update an entry in our function table to do something different!
FunctionSharedPointer op = GetFunction(FUNCTION_BUNNY);
FunctionSharedPointer np = std::make_shared<NewBunny>(op);
SetFunction(FUNCTION_BUNNY, np);
std::cout << "after:" << std::endl;
CallFunction(FUNCTION_BUNNY);
return 0;
}
void bunny()
{
cout << "The bunny jumped." << endl;
}
void oldBunny()
{
bunny();
}
void newBunny()
{
bunny();
cout << "The bunny also ran." << endl;
}
#define bunny newBunny
int main()
{
bunny();
return 0;
}
If you don't need oldBunny(), just remove it.
I'm writing a class where I would like to have some member methods that have some data associated with them, specifically which mechanical systems of a robot they require use of. I thought I could write them as functors, something like this (this isn't my actual code):
class MyRobot : public Robot {
public:
MyRobot();
void runRobot();
private:
Command do_something_,
do_another_thing_;
}
And then initialize do_something_ with a lambda in the constructor like:
do_something_( [] {
do_first_thing();
do_second_thing();
} );
And then tell do_something_ what requirements it has:
do_something_.requires( system_a );
do_something_.requires( system_b );
And in runRobot() I would tell the robot's scheduler to execute the commands:
void MyRobot::runRobot() {
scheduler.add(do_something_);
scheduler.add(do_another_thing_);
}
But I have come to realize that as the number of commands grows, the less manageable the constructor for MyRobot will become, as every command will have its body defined there. I could make a corresponding private method for each command and initialize them with a function pointer instead of a lambda, but that just seems more convoluted. I could also subclass Command for each specific command and thereby have the body and requirements in a separate file for each one, but that feels like a lot of overhead for a fairly simple task. Is there a good way to do this that I'm not aware of?
You can define the Command class to take a std::function and an initializer list of "requirements" as you have them. Then, instead of using lambdas you can make do_something and do_another_thing their own private member functions so you don't have to define their bodies in the constructor. Finally, in the constructor you can construct the Command instances by binding the private member functions with the this pointer of the current MyRobot instance while also giving them a list of requirements. The Command objects should be able to modify the private state of MyRobot instances. An example is below. Also, see example output.
#include <functional>
#include <iostream>
#include <vector>
enum System { SYS_A, SYS_B, SYS_C };
class Command {
public:
typedef std::function<void()> FuncType;
Command(FuncType func, std::initializer_list<System> requirements)
:func_(func), requirements_(requirements) { }
void operator()() {
std::cout << "Executing Command:" << std::endl;
for ( System s : requirements_ )
std::cout << " REQUIRES " << static_cast<int>(s) << std::endl;
func_();
}
private:
FuncType func_;
std::vector<System> requirements_;
};
class Scheduler {
public:
void add(Command c) {
c();
}
};
class Robot {
public:
Robot()
:do_something_ (std::bind(&Robot::do_something, this), {SYS_A, SYS_B}),
do_another_thing_(std::bind(&Robot::do_another_thing, this), {SYS_A, SYS_C}) { }
void runRobot() {
s_.add(do_something_);
s_.add(do_another_thing_);
}
private:
void do_first_thing() { std::cout << " FIRST THING!" << std::endl; }
void do_second_thing() { std::cout << " SECOND THING!" << std::endl; }
void do_third_thing() { std::cout << " THIRD THING!" << std::endl; }
void do_something() { do_first_thing(); do_second_thing(); }
void do_another_thing() { do_first_thing(); do_third_thing(); }
Command do_something_;
Command do_another_thing_;
Scheduler s_;
};
int main(int, char**) {
Robot().runRobot();
}
I know this has been asked so many times, and because of that it's difficult to dig through the cruft and find a simple example of what works.
I've got this, it's simple and it works for MyClass...
#include <iostream>
using std::cout;
using std::endl;
class MyClass
{
public:
MyClass();
static void Callback(MyClass* instance, int x);
private:
int private_x;
};
class EventHandler
{
public:
void addHandler(MyClass* owner)
{
cout << "Handler added..." << endl;
//Let's pretend an event just occured
owner->Callback(owner,1);
}
};
EventHandler* handler;
MyClass::MyClass()
{
private_x = 5;
handler->addHandler(this);
}
void MyClass::Callback(MyClass* instance, int x)
{
cout << x + instance->private_x << endl;
}
int main(int argc, char** argv)
{
handler = new EventHandler();
MyClass* myClass = new MyClass();
}
class YourClass
{
public:
YourClass();
static void Callback(YourClass* instance, int x);
};
How can that be rewritten so EventHandler::addHandler() will work with both MyClass and YourClass. I'm sorry but it's just the way my brain works, I need to see a simple example of what works before I can comprehend why/how it works. If you've got a favorite way to make this work now's the time to show it off, please markup that code and post it back.
[edit]
It was answered but the answer was deleted before I could give the checkmark.
The answer in my case was a templated function. Changed addHandler to this...
class EventHandler
{
public:
template<typename T>
void addHandler(T* owner)
{
cout << "Handler added..." << endl;
//Let's pretend an event just occured
owner->Callback(owner,1);
}
};
Instead of having static methods and passing around a pointer to the class instance, you could use functionality in the new C++11 standard: std::function and std::bind:
#include <functional>
class EventHandler
{
public:
void addHandler(std::function<void(int)> callback)
{
cout << "Handler added..." << endl;
// Let's pretend an event just occured
callback(1);
}
};
The addHandler method now accepts a std::function argument, and this "function object" have no return value and takes an integer as argument.
To bind it to a specific function, you use std::bind:
class MyClass
{
public:
MyClass();
// Note: No longer marked `static`, and only takes the actual argument
void Callback(int x);
private:
int private_x;
};
MyClass::MyClass()
{
using namespace std::placeholders; // for `_1`
private_x = 5;
handler->addHandler(std::bind(&MyClass::Callback, this, _1));
}
void MyClass::Callback(int x)
{
// No longer needs an explicit `instance` argument,
// as `this` is set up properly
cout << x + private_x << endl;
}
You need to use std::bind when adding the handler, as you explicitly needs to specify the otherwise implicit this pointer as an argument. If you have a free-standing function, you don't have to use std::bind:
void freeStandingCallback(int x)
{
// ...
}
int main()
{
// ...
handler->addHandler(freeStandingCallback);
}
Having the event handler use std::function objects, also makes it possible to use the new C++11 lambda functions:
handler->addHandler([](int x) { std::cout << "x is " << x << '\n'; });
Here's a concise version that works with class method callbacks and with regular function callbacks. In this example, to show how parameters are handled, the callback function takes two parameters: bool and int.
class Caller {
template<class T> void addCallback(T* const object, void(T::* const mf)(bool,int))
{
using namespace std::placeholders;
callbacks_.emplace_back(std::bind(mf, object, _1, _2));
}
void addCallback(void(* const fun)(bool,int))
{
callbacks_.emplace_back(fun);
}
void callCallbacks(bool firstval, int secondval)
{
for (const auto& cb : callbacks_)
cb(firstval, secondval);
}
private:
std::vector<std::function<void(bool,int)>> callbacks_;
}
class Callee {
void MyFunction(bool,int);
}
//then, somewhere in Callee, to add the callback, given a pointer to Caller `ptr`
ptr->addCallback(this, &Callee::MyFunction);
//or to add a call back to a regular function
ptr->addCallback(&MyRegularFunction);
This restricts the C++11-specific code to the addCallback method and private data in class Caller. To me, at least, this minimizes the chance of making mistakes when implementing it.
Note that with C++20's bind_front you can simplify add_callback for class member functions to:
template<class T> void addCallback(T* const object, void(T::* const mf)(bool,int))
{
callbacks_.emplace_back(std::bind_front(mf, object));
}
What you want to do is to make an interface which handles this code and all your classes implement the interface.
class IEventListener{
public:
void OnEvent(int x) = 0; // renamed Callback to OnEvent removed the instance, you can add it back if you want.
};
class MyClass :public IEventListener
{
...
void OnEvent(int x); //typically such a function is NOT static. This wont work if it is static.
};
class YourClass :public IEventListener
{
Note that for this to work the "Callback" function is non static which i believe is an improvement. If you want it to be static, you need to do it as JaredC suggests with templates.
A complete working example from the code above.... for C++11:
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#if __cplusplus <= 199711L
#error This file needs at least a C++11 compliant compiler, try using:
#error $ g++ -std=c++11 ..
#endif
using namespace std;
class EventHandler {
public:
void addHandler(std::function<void(int)> callback) {
printf("\nHandler added...");
// Let's pretend an event just occured
callback(1);
}
};
class MyClass
{
public:
MyClass(int);
// Note: No longer marked `static`, and only takes the actual argument
void Callback(int x);
private:
EventHandler *pHandler;
int private_x;
};
MyClass::MyClass(int value) {
using namespace std::placeholders; // for `_1`
pHandler = new EventHandler();
private_x = value;
pHandler->addHandler(std::bind(&MyClass::Callback, this, _1));
}
void MyClass::Callback(int x) {
// No longer needs an explicit `instance` argument,
// as `this` is set up properly
printf("\nResult:%d\n\n", (x+private_x));
}
// Main method
int main(int argc, char const *argv[]) {
printf("\nCompiler:%ld\n", __cplusplus);
new MyClass(5);
return 0;
}
// where $1 is your .cpp file name... this is the command used:
// g++ -std=c++11 -Wall -o $1 $1.cpp
// chmod 700 $1
// ./$1
Output should be:
Compiler:201103
Handler added...
Result:6
MyClass and YourClass could both be derived from SomeonesClass which has an abstract (virtual) Callback method. Your addHandler would accept objects of type SomeonesClass and MyClass and YourClass can override Callback to provide their specific implementation of callback behavior.
If you have callbacks with different parameters you can use templates as follows:
// compile with: g++ -std=c++11 myTemplatedCPPcallbacks.cpp -o myTemplatedCPPcallbacksApp
#include <functional> // c++11
#include <iostream> // due to: cout
using std::cout;
using std::endl;
class MyClass
{
public:
MyClass();
static void Callback(MyClass* instance, int x);
private:
int private_x;
};
class OtherClass
{
public:
OtherClass();
static void Callback(OtherClass* instance, std::string str);
private:
std::string private_str;
};
class EventHandler
{
public:
template<typename T, class T2>
void addHandler(T* owner, T2 arg2)
{
cout << "\nHandler added..." << endl;
//Let's pretend an event just occured
owner->Callback(owner, arg2);
}
};
MyClass::MyClass()
{
EventHandler* handler;
private_x = 4;
handler->addHandler(this, private_x);
}
OtherClass::OtherClass()
{
EventHandler* handler;
private_str = "moh ";
handler->addHandler(this, private_str );
}
void MyClass::Callback(MyClass* instance, int x)
{
cout << " MyClass::Callback(MyClass* instance, int x) ==> "
<< 6 + x + instance->private_x << endl;
}
void OtherClass::Callback(OtherClass* instance, std::string private_str)
{
cout << " OtherClass::Callback(OtherClass* instance, std::string private_str) ==> "
<< " Hello " << instance->private_str << endl;
}
int main(int argc, char** argv)
{
EventHandler* handler;
handler = new EventHandler();
MyClass* myClass = new MyClass();
OtherClass* myOtherClass = new OtherClass();
}
I have the following code:
#include <iostream>
using namespace std;
class A
{
int m_value;
public:
A(int value)
{
m_value = value;
funcA(&A::param);
}
void funcA(void (A::*function)(int))
{
(this->*function)(m_value);
}
void param(int i)
{
cout << "i = " << i << endl;
}
};
int main()
{
A ob(10);
return 0;
}
I have a class in which I call a function that receives another function as parameter. The function call is at line funcA(&A::param). What I want is to be able to pass a function as parameter without being necessary to specify the class scope: funcA(¶m). Also I didn't want to use typedefs that's why I have the code a little 'dirty'.
Is there any possibility to achieve this?
This cannot be done. A function pointer in a class must be identified using the class scope (A::function)
That is kind of ugly.
The first thing you should look at doing is recoding things to use inheritence and dynamic dispatch instead. To do this you change the A class to have a virtual method that funcA calls
class A {
...
void funcA () {
custom_function(m_value);
}
protected:
virtual void custom_function (int)=0;
}
Now for every different custom_function you want to use, you declare a new class derived from A, and implement the function in there. It will automagically get called from funcA:
class A_print : public A {
public:
virtual void custom_function (int param) {
std::cout << "param was " << param << std::endl;
}
}
If that isn't flexible enough for you, the next best C++-ish solution would be to implement a functor (an object that acts as a function, possibly even overriding the ()operator.
I don't understand why you can't just do this:
#include <iostream>
using namespace std;
class A
{
int m_value;
public:
A(int value)
{
param(value);
}
void param(int i)
{
cout << "i = " << i << endl;
}
};
int main()
{
A ob(10);
return 0;
}
I want the Windows thread pool (QueueUserWorkItem()) to call my class' member functions.
Unfortunately this cannot be done directly by passing a member function pointer as an argument to QueueUserWorkItem().
What makes it difficult is that more than one member function must be callable and they have different signatures (all return void though).
One probably need to add a few layers of abstraction to get this to work, but I'm not sure how to approach this. Any ideas?
This might help.
You can use tr1::function () and tr1::bind to "coalesce" various calls:
#include <iostream>
#include <tr1/functional>
using namespace std;
using namespace tr1;
class A
{
public:
void function(int i) { cout << "Called A::function with i=" << i << endl; }
};
void different_function(double c) {
cout << "Called different_function with c=" << c << endl;
}
int main(int argc, char* argv[])
{
function<void()> f = bind(different_function, 3.14165);
f();
A a;
f = bind(&A::function, a, 10);
f();
return 0;
}
The address of the function object can be passed as a single callable object (needing only one address).
Example:
In your class add:
char m_FuncToCall;
static DWORD __stdcall myclass::ThreadStartRoutine(LPVOID myclassref)
{
myclass* _val = (myclass*)myclassref;
switch(m_FuncToCall)
{
case 0:
_val->StartMyOperation();
break;
}
return 0;
}
Make a member for adding to queue then
void myclass::AddToQueue(char funcId)
{
m_FuncToCall=funcId;
QueueUserWorkItem(ThreadStartRoutine,this,WT_EXECUTEDEFAULT);
}
or create
typedef void (*MY_FUNC)(void);
typedef struct _ARGUMENT_TO_PASS
{
myclass* classref;
MY_FUNC func;
}ARGUMENT_TO_PASS;
and then
void myclass::AddToQueue(MY_FUNC func)
{
ARGUMENT_TO_PASS _arg;
_arg.func = func;
_arg.classref = this;
QueueUserWorkItem(ThreadStartRoutine,&_arg,WT_EXECUTEDEFAULT);
}
If you need further explanation feel free to ask :)
EDIT: You'll need to change the ThreadStartRoutine for the second example
and you can also change the struct to hold the passing argument