устранение перегрузок в boost.python - PullRequest
1 голос
/ 13 марта 2010

У меня есть класс C ++, подобный этому:

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

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

Мои шаблоны и перегрузки являются известным фиксированным набором типов во время компиляции. Код приложения является производным от 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 Ответ

2 голосов
/ 13 марта 2010

Создание виртуальных функций C ++, которые могут быть переопределены в Python, требует некоторой работы - см. здесь . Вам нужно будет создать функцию-обертку в производном классе, который вызывает метод 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.
    ;
}

Некоторые заметки:

  • Поскольку вы не будете вызывать функцию OnEvent базового класса из Python, вам не нужно определять ее с помощью .def. Если вы хотите определить его, вам нужно дать двум перегруженным версиям разные имена, например здесь.

  • Две перегрузки будут вызывать разные методы Python: OnEventOverloadA и OnEventOverloadB. Другой вариант - заставить их обоих вызывать один и тот же метод OnEvent, а затем один метод Python переопределит обе перегрузки.

...