Palace Chan
Palace Chan

Reputation: 9183

Bind arguments to function in two steps in c++?

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

Answers (1)

Dan Hulme
Dan Hulme

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:

  • It lets you give names to the 'delegate' type 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.
  • It lets you choose in the Manager class and any derived classes whether to inherit from ThingDoer, or have a nested (private or protected) class that inherits ThingDoer.
  • If you want to add an extra function to the interface later (to make it do two different things), it's easier to do that, and you won't be tempted to simply add more and more function objects. (But it's only easier later because you've already paid the extra cost of writing your code this way.)
  • If you have programmers from the Java or C# communities, they'll probably be more familiar with code like this.

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

Related Questions