解决boost.python中的重载问题

时间:2010-03-12 21:36:13

标签: c++ python boost boost-python

我有一个像这样的C ++类:

class ConnectionBase
{
public:
    ConnectionBase();
    template <class T> Publish(const T&);

private:
    virtual void OnEvent(const Overload_a&) {}
    virtual void OnEvent(const Overload_b&) {}
};

我的模板&amp;重载是编译时已知的固定类型集。应用程序代码派生自ConnectionBase,并为其关注的事件重写OnEvent。我可以这样做,因为已知类型集。 OnEvent是私有的,因为用户从不调用它,该类创建一个调用它作为回调的线程。 C ++代码有效。

我已将它包装在boost.python中,我可以导入它并从python发布。我想在python中创建以下等价物:

class ConnectionDerived
{
public:
    ConnectionDerived();

private:
    virtual void OnEvent(const Overload_b&)
    { 
        // application code
    }
};

我不关心(不想)暴露默认的OnEvent函数,因为它们从未从应用程序代码中调用 - 我只想为C ++类提供一个体来调用。 但是......因为python没有输入,而且我看到处理内部的所有boost.python示例都在C ++方面,我对如何做到这一点感到有些困惑。如何覆盖特定的重载?

1 个答案:

答案 0 :(得分:2)

创建可以在Python中重写的C ++虚拟函数需要一些工作 - 请参阅here。您需要在派生类中创建一个调用Python方法的包装函数。以下是它的工作原理:

struct ConnectionBaseWrap : ConnectionBase, wrapper<ConnectionBase>
{
    void OnEvent(const Overload_a &obj) {
        if (override f = get_override("OnEventOverloadA"))
            f(obj);
    }
    void OnEvent(const Overload_b &obj) {
        if (override f = get_override("OnEventOverloadB"))
            f(obj);
    }
};

BOOST_PYTHON_MODULE(yourmodule) {
    class_<ConnectionBaseWrap, boost::noncopyable>("ConnectionBase")
        //Your additional definitions here.
    ;
}

一些注意事项:

  • 由于您不会从Python调用基类的OnEvent函数,因此您无需使用.def定义它。如果您确实想要定义它,则需要为两个重载版本提供不同的名称,例如here.

  • 这两个重载会调用不同的Python方法:OnEventOverloadAOnEventOverloadB。另一个选择是让它们都调用相同的方法OnEvent,然后一个Python方法将覆盖两个重载。