基于boost::python,Python中繼承C++的類型并覆寫虛方法

官方文檔的Wrapper建議

C++代碼:

class TestBase
{
public:
    virtual void f() 
    {
        cout<<"cpp: call TestBase f"<<endl;
    }
};

class TestBaseWrapper : public TestBase, public wrapper<TestBase>
{
public:
    void f() override
    {
        cout << "cpp: call TestBaseWrapper f" << endl;
        if (auto f = this->get_override("f"))
        {
            f();
            return;
        }
        this->TestBase::f();
    }

    void default_f() 
    {
        cout << "cpp: call TestBaseWrapper default_f" << endl;
        this->TestBase::f();
    }
};
class_<TestBaseWrapper, boost::noncopyable>("TestBase", init<>())
    .def("f", &TestBase::f, &TestBaseWrapper::default_f)
    ;

python 調(diào)用

Python測(cè)試代碼:

TestBase().f()

cpp: call TestBaseWrapper default_f
cpp: call TestBase f

class TestPySub1(TestBase):
    pass
TestPySub1().f()

cpp: call TestBaseWrapper default_f
cpp: call TestBase f

class TestPySub2(TestBase):
    def f(self):
        print "py: call TestPySub2 f"
TestPySub2().f()

py: call TestPySub2 f

結(jié)論:

從python層調(diào)用 f()

未覆寫方法 -> TestBaseWrapper::default_f()

已覆寫 -> py覆寫的 f()


C++ 調(diào)用

C++代碼:

void test(TestBase* obj)
{
    obj->f();
}

def("test", &test);

Python測(cè)試代碼:

test(TestBase())

cpp: call TestBaseWrapper f
cpp: call TestBase f

class TestPySub1(TestBase):
    pass
test(TestPySub1())

cpp: call TestBaseWrapper f
cpp: call TestBase f

class TestPySub2(TestBase):
    def f(self):
        print "py: call TestPySub2 f"
test(TestPySub2())

cpp: call TestBaseWrapper f
py: call TestPySub2 f

結(jié)論:

從C++層調(diào)用 f()

調(diào)用TestBaseWrapper::f()

未覆寫方法 -> TestBase::f()

已覆寫 -> py覆寫的 f()


嘗試簡(jiǎn)化

C++代碼:

class TestBase :public wrapper<TestBase>
{
public:
    virtual void f() 
    {
        cout<<"cpp: call TestBase f"<<endl;
    }

    void f_()
    {
        cout << "cpp: call TestBase f_" << endl;
        if (auto f = this->get_override("f"))
        {
            f();
            return;
        }
        this->f();
    }
};
class_<TestBase, boost::noncopyable>("TestBase", init<>())
    .def("f", &TestBase::f)
    ;

Python 調(diào)用

Python測(cè)試代碼

TestBase().f()

cpp: call TestBase f

class TestPySub1(TestBase):
    pass
TestPySub1().f()

cpp: call TestBase f

class TestPySub2(TestBase):
    def f(self):
        print "py: call TestPySub2 f"
TestPySub2().f()

py: call TestPySub2 f

結(jié)論:

從python層調(diào)用 f()

未覆寫方法 -> TestBase::f()

已覆寫 -> py覆寫的 f()


C++ 調(diào)用

C++代碼:

void test(TestBase* obj)
{
    obj->f_();
}

def("test", &test);

Python測(cè)試代碼:

test(TestBase())

cpp: call TestBase f_
cpp: call TestBase f

class TestPySub1(TestBase):
    pass
test(TestPySub1())

cpp: call TestBase f_
cpp: call TestBase f

class TestPySub2(TestBase):
    def f(self):
        print "py: call TestPySub2 f"
test(TestPySub2())

cpp: call TestBase f_
py: call TestPySub2 f

結(jié)論:

從C++層調(diào)用 f()

調(diào)用TestBase::f_()

未覆寫方法 -> TestBase::f()

已覆寫 -> py覆寫的 f()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容