2010-05-07 5 views
2

У меня возникли проблемы с тем, что лучший способ обернуть серию классов с помощью Boost.Python, избегая беспорядочных проблем наследования. Скажем, у меня есть классы A, B и C со следующей структурой:Иерархии пакетов Boost.Python, избегающие наследования алмазов

struct A { 
    virtual void foo(); 
    virtual void bar(); 
    virtual void baz(); 
}; 

struct B : public A { 
    virtual void quux(); 
}; 

struct C : public A { 
    virtual void foobar(); 
}; 

Я хочу, чтобы обернуть все классы A, B и C таких, что они расширяемые с Python. Обычный способ для достижения этого было бы по линии:

struct A_Wrapper : public A, boost::python::wrapper<A> { 
    //dispatch logic for virtual functions 
}; 

Теперь для классов В и С, которые простираются от ИИ хотел бы, чтобы иметь возможность наследовать и разделить реализацию оберточную для А. Так что я хотел бы чтобы быть в состоянии сделать что-то вдоль линий:

struct B_Wrapper : public B, public A_Wrapper, public boost::python::wrapper<B> { 
    //dispatch logic specific for B 
}; 

struct C_Wrapper : public C, public A_Wrapper, public boost::python::wrapper<C> { 
    //dispatch logic specific for C 
} 

Однако, похоже, что бы ввести всякие гадости с двойным наследованию форсированной обертки базы и двойным наследованием а в B_Wrapper и C_Wrapper объекты. Есть ли общий способ, чтобы этот экземпляр был решен, что я пропал?

спасибо.

ответ

1

Один из подходов состоит в получении практически:

struct B : virtual public A, ... { }; 
struct C : virtual public A, ... { }; 
struct A_Wrapper : virtual public A, ... { }; 

Смотрите соответствующую C++ FAQ Lite items для заметок и что это означает.

+0

Спасибо за ваш ответ. Как насчет того, когда я не могу изменить отношения наследования, чтобы воспользоваться виртуальным наследованием? Это решение также пришло мне в голову, но оно не слишком привлекательно и слишком навязчиво. Конечно, это довольно распространенная операция, то есть обертывание иерархии типов, в которой многократные нелистовые точки в иерархии могут быть расширены через Python, но мне не удалось найти их. – user21714

1

У меня была точно такая же проблема, и я просто не унаследовал B_Wrapper от A_Wrapper (копии и вставки было достаточно для моих нужд). Я думаю, что можно разделить общую реализацию в вспомогательном классе:

template<class ADERIVED> 
struct A_Implem: public ADERIVED, public wrapper<ADERIVED> 
{ 
    // dispatch logic 
}; 

А потом:

struct A_Wrapper: public A_Implem<A> 
{ 
// ... 
}; 


struct B_Wrapper: public A_Implem<B> 
{ 
// ... 
}; 
+0

Да, это на самом деле решение, которое у меня есть на данный момент. Это работоспособно, но для меня это кажется довольно неуклюжим. Я надеялся, что есть что-то, чего я просто не видел. Но, возможно, это единственный неинтрузивный вариант. – user21714

+0

Кажется, что это работает, только если A, B и C принимают одинаковое количество аргументов конструктора, так как A_Implem знает, как вызвать конструктор ADERIVED. Или я чего-то не хватает? –