“接口”就像使用boost :: bind的语义一样

时间:2010-10-27 22:31:22

标签: c++ boost boost-bind

我希望能够像C ++一样使用Java的接口语义。起初,我使用boost::signal来回调给定事件的显式注册成员函数。这非常有效。

但后来我决定一些函数回调池是相关的,抽象它们并立即注册所有实例的相关回调是有意义的。但我学到的是boost::bind的特定性质和/或取this的价值似乎使得这种突破。或者可能只是add_listener(X &x)方法声明改变了boost::bind生成的代码。

我非常粗略地理解为什么会出现这个问题,而且我认为它的设计可能正常运行。我很好奇:应该我做了什么?当然,有一种正确的方法可以做到这一点。

以下是一些示例代码:

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

好的,我没有完全描述这个问题。这个标题具有误导性。

哦,伙计。请注意这个。我显然没有很好地描述这个问题,我认为这最终归结为语法错误。 :(

2 个答案:

答案 0 :(得分:3)

boost::bind按值获取参数并复制它们。这意味着

f = boost::bind<void>(boost::mem_fn(&X::go), x);

将传递x副本,它会切掉Y段的Y(如果它真的是boost::bind开头)。要使虚拟调度工作,您需要将指针传递给f = boost::bind(&X::go, &x);

mem_fn

(请注意,您实际上不需要<void>,或明确写boost::bind,因为{{1}}和参数演绎会为您处理。{/ p>

答案 1 :(得分:0)

Java接口并不特别存在于C ++中。最接近的是纯抽象基类。这通常非常接近。

您的其余问题与接口无关。 Java使用Observer模式进行事件连接和调度。接口部分只是温和相关,因为观察者必须服从特定的接口(当然,否则你不知道该怎么叫)。

使用boost :: bind来创建仿函数实际上是接口之外的抽象,因此是一种更通用的解决方案。观察者模式和仿函数被组合成信号/插槽习语/模式,在各种库中实现,如boost :: signals,boost :: signals2和gtk ++。 Qt版本在力学方面有很大的不同,但在概念上却相似。

那么,这有什么意义可以帮助您了解什么,为什么以及在哪里?我建议先从Observer模式的搜索开始,然后尝试编写一些实现。