読者です 読者をやめる 読者になる 読者になる

boost.pythonでvirtualのoverride

http://svn.sourceforge.jp/svnroot/shive/junk/diary/2009/20091216_override.tar.gz
やってみた。

class Person
{
public:
    Person() {
    }
    virtual ~Person() {
    }
    void say() {
        printf("[%08X]%s\n", (uintptr_t)this, _what());
    }

    virtual const char* _what() const {
        return "person!!";
    }
};

struct PersonWrapper : Person, boost::python::wrapper<Person>
{
    virtual const char* _what() const {
        if(boost::python::override func = get_override("_what")){
            return func();
        }
        return Person::_what();
    }
};

BOOST_PYTHON_MODULE(person)
{
    using namespace boost;
    using namespace boost::python;

    class_<PersonWrapper, noncopyable>("Person", "<<< document here >>>")
        .def("say", &Person::say);
}
from person import *

class Human(Person):
    def __init__(self):
        super(Human, self).__init__()
    def _what(self):
        return 'human!!'


person = Person()
print type(person)
person.say()

human = Human()
print type(human)
human.say()
$ scons -Q test
python test.py
<class 'person.Person'>
[00C68490]person!!
<class '__main__.Human'>
[00C68520]human!!

boost::python::wrapperを継承した派生クラスで一度python側へoverrideがあるか問い合わせ、あったらそっちを実行。無かったら基底を実行。てな具合に動くのかな?
scons使ってるのでステップ実行までしなくなってしまった。emacs用にデバッグ環境用意せんとな〜。

参考

余談

やってて思ったけど、swigで生のpythonラッパ吐くんじゃなくて、boost.python用のラッパって吐けないのかな?
と思ったらやっぱりそれっぽいのがあった→http://language-binding.net/pyplusplus/pyplusplus.html