问题描述
我希望能够有东西像C ++ Java的接口语义。起初,我用了的boost ::信号
回调明确登记的成员函数对于给定的事件。这确实行之有效。
I wanted to be able to have something like Java's interface semantics with C++. At first, I had used boost::signal
to callback explicitly registered member functions for a given event. This worked really well.
但后来我决定,函数回调的一些池均与它抽象有意义他们,一次注册的所有实例的相关的回调。但我了解到的是,的boost ::绑定
和/或获取价值的具体性质这个
似乎作出这样的突破。也许这就是刚才说的 add_listener(X安培; X)的事实
方法声明中改变了code,它的boost ::绑定
生成的。
But then I decided that some pools of function callbacks were related and it made sense to abstract them and register for all of an instance's related callbacks at once. But what I learned was that the specific nature of boost::bind
and/or taking the value of this
seemed to make that break. Or perhaps it was just the fact that the add_listener(X &x)
method declaration changed the code that boost::bind
generated.
我有一个非常粗略的了解,为什么出现问题,我认为这可能是正常按照它的设计。我很好奇:什么应的我做了呢?当然,有一个正确的方式来做到这一点。
I have a very rough understanding why the problem occurred and I think it's probably functioning correctly as per its design. I am curious: what should I have done instead? Surely there's a Right Way to do it.
下面是一些例子code:
Here's some example code:
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
using namespace std;
struct X;
struct Callback
{
virtual void add_listener(X &x) = 0;
};
struct X
{
X() {}
X(Callback &c) { c.add_listener(*this); }
virtual void go() { cout << "\t'" << __PRETTY_FUNCTION__ << "'" << endl; }
};
struct CallbackReal : public Callback
{
virtual void add_listener(X &x)
{
f = boost::bind<void>(boost::mem_fn(&X::go), x);
}
void go() { f(); }
boost::function<void (void)> f;
};
struct Y : public X
{
Y() {}
Y(Callback &c) { c.add_listener(*this); }
virtual void go() { cout << "\t'" << __PRETTY_FUNCTION__ << "'" << endl; }
};
int main(void)
{
CallbackReal c_x;
CallbackReal c_y;
X x(c_x);
Y y(c_y);
cout << "Should be 'X'" << endl;
boost::bind<void>(boost::mem_fn(&X::go), x)();
cout << "Should be 'Y'" << endl;
boost::bind<void>(boost::mem_fn(&X::go), y)();
cout << "------------------" << endl;
cout << "Should be 'X'" << endl;
c_x.go();
cout << "I wish it were 'Y'" << endl;
c_y.go();
return 0;
}
好吧,我并没有完全说明问题。标题是误导性的。
Okay, I did not describe the problem completely. The title is misleading.
哦,伙计。 Downvote这一个。我显然还没有描述的问题很好,我想这最终归结为一个主要语法错误。 (
推荐答案
的boost ::绑定
按价值计算,它们拷贝需要它的参数。这意味着
boost::bind
takes its parameters by value and copies them. That means
f = boost::bind<void>(boost::mem_fn(&X::go), x);
将传递一个的复制的的 X
,将切下的是
片它(如果它真的是一个是
来开头)。为了得到虚拟调度工作,你需要一个指针传递给的boost ::绑定
:
will pass a copy of x
, which will slice off the Y
piece of it (if it was really a Y
to begin with). To get virtual dispatch to work, you need to pass a pointer to boost::bind
:
f = boost::bind(&X::go, &x);
(请注意,您实际上并不需要的mem_fn
,或明确写入&LT;无效&GT;
,因为的boost ::绑定
和参数推导照顾那些对你的。)
(Note that you don't actually need mem_fn
, or to explicitly write <void>
, since boost::bind
and argument deduction take care of those for you.)
这篇关于&QUOT;接口与QUOT;喜欢用的boost ::绑定语义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!