• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[section boost/python/wrapper.hpp]
2[section Introduction]
3To wrap a class T such that its virtual functions can be "overridden in Python"—so that the corresponding method of a Python derived class will be called when the virtual function is invoked from C++—you must create a C++ wrapper class derived from `T` that overrides those virtual functions so that they call into Python. This header contains classes that can be used to make that job easier.
4[endsect]
5[section Class `override`]
6Encapsulates a Python override of a C++ virtual function. An override object either holds a callable Python object or `None`.
7``
8namespace boost
9{
10  class override : object
11  {
12   public:
13      unspecified operator() const;
14      template <class A0>
15      unspecified operator(A0) const;
16      template <class A0, class A1>
17      unspecified operator(A0, A1) const;
18      ...
19      template <class A0, class A1, ...class An>
20      unspecified operator(A0, A1, ...An) const;
21  };
22};
23``
24[endsect]
25[section Class `override` observer functions]
26``
27unspecified operator() const;
28template <class A0>
29unspecified operator(A0) const;
30template <class A0, class A1>
31unspecified operator(A0, A1) const;
32...
33template <class A0, class A1, ...class An>
34unspecified operator(A0, A1, ...An) const;
35``
36[variablelist
37[[Effects][If *this holds a callable Python object, it is invoked with the specified arguments in the manner specified here. Otherwise, throws [link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set].]]
38[[Returns][An object of unspecified type that holds the Python result of the invocation and, when converted to a C++ type R, attempts to convert that result object to R. If that conversion fails, throws [link high_level_components.boost_python_errors_hpp.class_error_already_set error_already_set].]]
39]
40[endsect]
41[section Class template `wrapper`]
42Deriving your wrapper class from both `T` and `wrapper<T>` makes writing that derived class easier.
43``
44namespace boost
45{
46  class wrapper
47  {
48   protected:
49      override get_override(char const* name) const;
50  };
51};
52``
53[endsect]
54[section Class template `wrapper` observer functions]
55``override get_override(char const* name) const;``
56[variablelist
57[[Requires][name is a [link ntbs].]]
58[[Returns][If `*this` is the C++ base class subobject of a Python derived class instance that overrides the named function, returns an override object that delegates to the Python override. Otherwise, returns an override object that holds `None`.]]
59]
60[endsect]
61[section Example]
62``
63#include <boost/python/module.hpp>
64#include <boost/python/class.hpp>
65#include <boost/python/wrapper.hpp>
66#include <boost/python/call.hpp>
67
68using namespace boost::python;
69
70// Class with one pure virtual function
71struct P
72{
73    virtual ~P(){}
74    virtual char const* f() = 0;
75    char const* g() { return "P::g()"; }
76};
77
78struct PCallback : P, wrapper<P>
79{
80    char const* f()
81    {
82        return this->get_override("f")();
83    }
84};
85
86// Class with one non-pure virtual function
87struct A
88{
89    virtual ~A(){}
90    virtual char const* f() { return "A::f()"; }
91};
92
93struct ACallback :  A, wrapper<A>
94{
95    char const* f()
96    {
97        if (override f = this->get_override("f"))
98            return f();
99        return A::f();
100    }
101
102    char const* default_f() { return this->A::f(); }
103};
104
105BOOST_PYTHON_MODULE_INIT(polymorphism)
106{
107    class_<PCallback,boost::noncopyable>("P")
108        .def("f", pure_virtual(&P::f))
109        ;
110
111    class_<ACallback,boost::noncopyable>("A")
112        .def("f", &A::f, &ACallback::default_f)
113        ;
114}
115``
116[endsect]
117[endsect]
118