我有一个类管理器和一个类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;
}
我怎样才能做到这一点(可能有升压功能或类似的东西)?
答案 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的嵌套(私有或受保护)类。可能在您的情况下,这些都不是优势,在这种情况下,一定要使用ThingDoer
/ boost::function
解决方案。我在类似的情况下做了同样的事情。我可能也应该提到C ++ 11在boost::bind
本身中具有大部分或全部功能绑定功能。