在c ++中将参数绑定到两个步骤?

时间:2012-06-26 19:40:33

标签: c++ boost

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

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

我怎样才能做到这一点(可能有升压功能或类似的东西)?

1 个答案:

答案 0 :(得分: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()>)。调用boost::function的开销略高于虚函数调用。

我不确定你的具体情况,但是如果你真的定义了一个代表f的功能的抽象基类,你可能最终得到一个更好的接口,并拥有{{1}的构造函数而Base取一个抽象基类的对象,如下所示: -

A

其中A的构造函数具有签名struct ThingDoer { virtual void do() = 0; }; class Manager : private ThingDoer { virtual void do() { ... } void createThing() { Base *b = new A(this); } };

如果您之前已经阅读过“委托”设计模式,那么您就知道我的意思了。在这个简单,抽象的例子中,它看起来比使用A(ThingDoer*)的解决方案看起来更笨拙和更长,但它确实对真实软件有潜在优势:

  • 它允许您为“委托”类型boost::function,您对该类型的实现以及其中的函数指定名称。此外,如果您使用Doxygen或其他结构化注释系统,则记录委托类比使用函数对象参数容易得多。
  • 它允许您在ThingDoer类和任何派生类中选择是继承自Manager还是具有继承ThingDoer的嵌套(私有或受保护)类。
  • 如果你想稍后在界面上添加一个额外的功能(让它做两件事),那么这样做会更容易,你不会想要简单地添加越来越多的功能对象。 (但之后更容易,因为您已经支付了以这种方式编写代码的额外费用。)
  • 如果您有来自Java或C#社区的程序员,他们可能会更熟悉这样的代码。

可能在您的情况下,这些都不是优势,在这种情况下,一定要使用ThingDoer / boost::function解决方案。我在类似的情况下做了同样的事情。我可能也应该提到C ++ 11在boost::bind本身中具有大部分或全部功能绑定功能。