Boost Python官方樣例(三)


導出C++類(純虛函數和虛函數)

大致做法就是為class寫一個warp,通過get_override方法檢測虛函數是否被重載了,如果被重載了調用重載函數,否則調用自身實現,最后導出的時候直接導出warp類,但是類名使用class,析構函數不需要導出,因為它會被自動調用

純虛函數

編寫C++函數實現

$ vim virt.h
#include <iostream>
#include <boost/python/wrapper.hpp>

// 用class會出現編譯問題, 不知道是不是和boost::python里面的class產生了沖突
struct Base
{
    virtual ~Base() { std::cout << "Base destructor" << std::endl; };
    virtual int f() = 0;
};

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

編寫Boost.Python文件

$ vim virt_wrapper.cpp
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/pure_virtual.hpp>
#include "virt.h"

using namespace boost::python;
using namespace boost::python::detail;

BOOST_PYTHON_MODULE_INIT(virt_ext)
{
    class_<BaseWrap, boost::noncopyable>("Base")
            .def("f", pure_virtual(&Base::f));
}

運行python測試庫文件

$ python
>>> import virt_ext
>>> def f():
...     o = virt_ext.Base()
...
>>> f()
Base destructor

虛函數

編寫C++函數實現

$ vim virt.h
#include <boost/python/wrapper.hpp>
#include <boost/python/call.hpp>

struct Base
{
    virtual ~Base() { std::cout << "Base destructor" << std::endl; };
    virtual int f() = 0;
};

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

struct Derived: Base
{
    virtual ~Derived() { std::cout << "Derived destructor" << std::endl; }
    virtual int f() { std::cout << "Override by Derived" << std::endl; return 0; }
};

struct DerivedWrap : Derived, boost::python::wrapper<Derived>
{
    int f()
    {
        if (boost::python::override func = this->get_override("f"))
            return func();
        return Derived::f();
    }
};

編寫Boost.Python文件

$ vim virt_wrapper.cpp
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/pure_virtual.hpp>
#include "virt.h"

using namespace boost::python;
using namespace boost::python::detail;

BOOST_PYTHON_MODULE_INIT(virt_ext)
{
// 可以導出Base也可以不導出Base
//    class_<BaseWrap, boost::noncopyable>("Base")
//            .def("f", pure_virtual(&Base::f));
    class_<DerivedWrap, boost::noncopyable>("Derived")
            .def("f", &Derived::f);
}

運行python測試庫文件

>>> import virt_ext
>>> b = virt_ext.Base()
>>> d = virt_ext.Derived()
>>> d.f()
Override by Derived
0
>>> b.f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: Pure virtual function called
>>> exit()
Base destructor
Derived destructor
Base destructor


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM