2013-01-31 53 views
1

我正在使用Boost Python爲C++中的某些類提供python接口。 我發現這個局面,我不知道如何解決:幾個具有不同簽名的虛擬成員函數

我有了這個成員函數的類:

virtual void visit(const ReportClass r) = 0; 
virtual void visit(const unsigned int category) = 0; 
virtual void visit(const char* type) = 0; 
virtual void visit(const char* name, const unsigned int id, const char &value) = 0; 
virtual void visit(const char* name, const unsigned int id, const unsigned short &value) = 0; 
virtual void visit(const char* name, const unsigned int id, const unsigned int &value) = 0; 
virtual void visit(const char* name, const unsigned int id, const MaskedAddr &value) = 0; 
virtual void visit(const char* name, const unsigned int id, const unsigned long long &value) = 0; 

我有點失去了對如何實現python- boost部分,我已經看到如何進行虛函數和重載函數,但我不知道如何將兩者結合起來。

順便說一下,我看到的是一個虛函數返回一個int(例如)應實施這樣的例子:

int f() 
{ 
    return this->get_override("f")(); 
} 

在我的情況下,他們不返回任何我想我應該以這種方式實施:

void f() 
{ 
    this->get_override("f")(); 
} 

這是正確的嗎?

在此先感謝

+3

** **亂收費的功能呢?那是什麼? –

+0

對不起,超載.... – RaistlinMolina

+0

您的立場正確。 –

回答

1

如果我正確理解你的問題,你要綁定純虛(重載)方法到Python,這樣他們就可以從蟒蛇超載。你有already found的教程,部分解釋。在你的具體情況下,C++和Python與超載不能很好地相互作用。雖然C++允許,但Python禁止。 Python中不能有兩個名稱爲f的方法。我們要做的就是分歧 python調用,所以用戶可以實現從Python重寫。

我會寫一個較小的例子,但是你可以從中抽象出來。

讓我們從C++管道開始吧。您的C++綁定應如下所示:

struct BaseWrap : Base, boost::python::wrapper<Base> { 
    int f() { 
     return this->get_override("__f1__")(); 
    } 

    int f(int i) { 
     return this->get_override("__f2__")() 
    } 

    int f(const char* s) { 
     return this->get_override("__f3__")() 
    } 

    int f(const char* s, double d) { 
     return this->get_override("__f4__")() 
    } 
}; 

//your module code will look like this 
BOOST_PYTHON_MODULE(example) { 
    using namespace boost::python; 
    class_<BaseWrap, boost::noncopyable>("Base") 
    .def("f", pure_virtual(((int)(Base::*)())&Base::f)) 
    .def("f", pure_virtual(((int)(Base::*)(int))&Base::f)) 
    .def("f", pure_virtual(((int)(Base::*)(const char*))&Base::f)) 
    .def("f", pure_virtual(((int)(Base::*)(const char*, double))&Base::f)) 
    ; 
} 

我們做了什麼?當代碼的Python端調用f(<parameters>)時,我們將解析爲正確的重載方法。然後這個方法將調用Python的__f1____f2__等,其中方法的肉實際上是從Python編碼的。

要完成綁定,在Python中,你必須從example.Base繼承,並實現__f1____f2____f3____f4__

class Base(example.Base): 
    """Throw here the documentation of Base - don't bother about the C++ stuff""" 

    def __init__(self,...): 
    pass 

    def __f1__(self): 
    """Implementation of Base::f()""" 
    pass 

    def __f2__(self): 
    """Implementation of Base::f(int)""" 
    pass 

    def __f3__(self): 
    """Implementation of Base::f(const char*)""" 
    pass 

    def __f4__(self): 
    """Implementation of Base::f(const char*, double)""" 
    pass 
1

讓我們先來簡單的問題:您可以隨時「返回這個 - > get_override(」 F「)();」,即使返回類型爲void。實際上,在這樣的包裝代碼中,我發現即使是更好的選擇,因爲如果突然包裝的函數返回一些東西,你會得到一個編譯錯誤!

現在的難題:如何在這裏混合使用虛函數和重載函數。我會使用模板方法模式規避這個問題。這個想法是簡單地提供一個公用的,非虛擬的函數來調用一個私有的虛函數。或者,您可以使虛擬人受到保護,以允許擴展而不是覆蓋。此外,在非虛擬環境中,您可以驗證派生類必須滿足或驗證參數的前/後條件(例如,assert(name);)。

相關問題