我有一个类 Manager 和一个类 Base(具有从 Base 派生的子类,比如 A:public Base)。在 Manager 内部,我创建了 Base 的正确子类,但随后 Base 忽略了 Manager 的存在。我想将一个绑定(bind)到 Manager 类的成员方法的函数对象传递到这个创建的 Base 子类中,以便调用 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;
}
我该如何着手做这件事(可能使用 boost 功能或类似的东西)?
最佳答案
如果您的 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 功能的抽象基类,并拥有 Base
的构造函数,您最终可能会得到一个更好的接口(interface)。和 A
取一个抽象基类的对象,像这样:-
struct ThingDoer
{
virtual void do() = 0;
};
class Manager : private ThingDoer
{
virtual void do()
{ ... }
void createThing()
{
Base *b = new A(this);
}
};
其中 A 的构造函数具有签名 A(ThingDoer*)
.
如果您以前读过“委托(delegate)”设计模式,您就会明白我的意思。在这个简单、抽象的示例中,它看起来比使用 boost::function
的解决方案更笨重、更长。 ,但它确实对真正的软件具有潜在优势:
- 它允许您为“委托(delegate)”类型命名
ThingDoer
,您对该类型的实现,以及其中的函数。此外,如果您使用 Doxygen 或其他一些结构化注释系统,记录委托(delegate)类比记录函数对象参数要容易得多。 - 它让你在
Manager
中选择类和任何派生类是否继承自ThingDoer
,或具有继承 ThingDoer 的嵌套(私有(private)或 protected )类。 - 如果您想稍后向界面添加一个额外的功能(让它做两件不同的事情),这样做会更容易,而且您不会想简单地添加越来越多的功能对象。 (但以后只会更容易,因为您已经支付了以这种方式编写代码的额外费用。)
- 如果您有来自 Java 或 C# 社区的程序员,他们可能会更熟悉这样的代码。
可能在您的情况下这些都不是优势,在这种情况下,一定要使用 boost::function
/boost::bind
解决方案。我在类似的情况下也做过同样的事情。我可能还应该提到,C++11 具有 std::
中的大部分或全部函数绑定(bind)功能。本身。
关于c++ - 在 C++ 中分两步将参数绑定(bind)到函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11214797/