Constructors

前記の例題では、明示的なコンストラクタが何もなかった。 World はさらの構造体として定義されていたのだから、 暗黙的なデフォルトコンストラクタしか持たない。 Boost.Python はデフォルトでデフォルトコンストラクタを開示するので、 例題を作成できたわけである。

    >>> planet = hello.World()

デフォルトコンストラクタではないクラスをラップしたいと思う。 前記の例題を再構築しよう。

    struct World
    {
        World(std::string msg): msg(msg) {} // added constructor
        void set(std::string msg) { this->msg = msg; }
        std::string greet() { return msg; }
        std::string msg;
    };

今度の World はデフォルトコンストラクタを持っていない。 前のラッピングコードは、ライブラリを開示しようとして、 コンパイルに失敗するだろう。 そのかわり、コンストラクタを開示する記述 class_<World> が必要である。

    #include <boost/python.hpp>
    using namespace boost::python;

    BOOST_PYTHON_MODULE(hello)
    {
        class_<World>("World", init<std::string>())
            .def("greet", &World::greet)
            .def("set", &World::set)
        ;
    }

init<std::string>()std::stringを持つコンストラクタを開示する。 (Pythonではコンストラクタは""__init__""と記述される。)

さらにinit<...>def()メンバ関数に続けて指定することによって、 コンストラクタを追加することができる。 たとえば、二つの実数引数を持つコンストラクタがある。

    class_<World>("World", init<std::string>())
        .def(init<double, double>())
        .def("greet", &World::greet)
        .def("set", &World::set)
    ;

一方コンストラクタを全く持ちたくないのであれば、 代わりにno_initを使うことができる。

    class_<Abstract>("Abstract", no_init)

これは、Pythonランタイムエラー例外を常に返すメソッド__init__を実際追加する。