0

我有一个类管理器和一个类 Base(具有从 Base 派生的子类,比如 A:public Base)。在 Manager 内部,我创建了 Base 的正确子类,但 Base 忽略了 Manager 的存在。我想将一个函数对象传递给这个创建的 Base 子类,该函数对象绑定到 Manager 类的成员方法,以供 A 对象调用。换句话说,在创建过程中,它会是这样的:

void Manager::createThing()
{
FunctionObject func;
if (doExtraWork)
    func.bind(&Manager::someMethod, this);

Base *bla = new A(func);
}

然后在 A 内部,我希望能够检测我们是否有额外的工作让经理继续我们并这样做,例如:

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

我该怎么做(可能使用增强功能或类似功能)?

4

1 回答 1

2

如果您的FunctionObject类型是boost::function<void()>,那么您可以从 的结果中分配给它boost::bind,如下所示:

boost::function<void()> f = boost::bind(&Manager::someMethod, this);
Base *b = new A(f);

其中 A 的构造函数有签名A(boost::function<void()>)。调用 a 的boost::function开销比虚函数调用稍多。

我对您的特定情况了解不多,无法确定,但是如果您实际上定义了一个代表 f 功能的抽象基类,并让您的构造函数获取BaseA获取抽象对象,那么您最终可能会得到一个更好的接口而是基类,如下所示:-

struct ThingDoer
{
    virtual void do() = 0;
};

class Manager : private ThingDoer
{
    virtual void do()
    { ... }

    void createThing()
    {
        Base *b = new A(this);
    }
};

其中 A 的构造函数有签名A(ThingDoer*)

如果你以前读过“委托”设计模式,你就会明白我的意思。在这个简单、抽象的示例中,它只是看起来比使用 的解决方案更笨重且更长boost::function,但它确实对实际软件具有潜在优势:

  • 它允许您为“委托”类型ThingDoer、该类型的实现以及其中的函数命名。此外,如果您使用 Doxygen 或其他一些结构化注释系统,则记录委托类比记录函数对象参数要容易得多。
  • 它允许您在Manager类和任何派生类中选择是继承自ThingDoer,还是具有继承 ThingDoer 的嵌套(私有或受保护)类。
  • 如果您以后想在接口中添加一个额外的功能(使其做两件不同的事情),这样做会更容易,而且您不会想简单地添加越来越多的功能对象。(但以后只会更容易,因为您已经支付了以这种方式编写代码的额外费用。)
  • 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.

于 2012-06-26T20:01:15.100 回答