Reputation: 9183
I have a class Manager and a class Base (with subclasses deriving from Base, say A : public Base). Inside Manager I create the right subclass of Base but then Base is oblivious to the existence of Manager. I wanted to pass into this created subclass of Base a function object bound to a member method of the Manager class for the A object to invoke. In other words during creation it would be something like this:
void Manager::createThing()
{
FunctionObject func;
if (doExtraWork)
func.bind(&Manager::someMethod, this);
Base *bla = new A(func);
}
Then inside of A, I would like to be able to detect whether we have extra work to have the Manager carry on us and do so, something like:
A::update()
{
if (func) //ideally detect if func was bound to someMethod or func is empty
func(this); //equivalent to the above instance of manager calling someMethod on this instance of A
//do regular stuff after;
}
How can I go about doing this (probably with boost function or something like that)?
Upvotes: 0
Views: 160
Reputation: 15290
If your FunctionObject
type is boost::function<void()>
, then you can assign to this from the result of boost::bind
, something like this:
boost::function<void()> f = boost::bind(&Manager::someMethod, this);
Base *b = new A(f);
where the constructor of A has signature A(boost::function<void()>)
. Calling a boost::function
has slightly more overhead than a virtual function call.
I don't know enough about your particular situation to know for sure, but you might end up with a better interface if you actually define an abstract base class representing the functionality of f, and have your constructor for Base
and A
take an object of the abstract base class instead, like this:-
struct ThingDoer
{
virtual void do() = 0;
};
class Manager : private ThingDoer
{
virtual void do()
{ ... }
void createThing()
{
Base *b = new A(this);
}
};
where the constructor of A has signature A(ThingDoer*)
.
If you've previously read about the 'delegate' design pattern, you know the kind of thing I mean. In this simple, abstract example, it just looks clunkier and longer than the solution using boost::function
, but it does have potential advantages for real software:
ThingDoer
, your implementation of that type, and the function inside it. Also, if you use Doxygen or some other structured comment system, it's a lot easier to document the delegate class than a function object parameter.Manager
class and any derived classes whether to inherit from ThingDoer
, or have a nested (private or protected) class that inherits ThingDoer.It may be that none of those are advantages in your situation, in which case, definitely use the boost::function
/ boost::bind
solution. I've done the same in similar situations. I probably ought to mention too that C++11 has most or all of the function-binding functionality in std::
itself.
Upvotes: 2