#pragma section-numbers off = Overridable Virtual Functions = In the previous example we exposed a simple C++ class in Python and showed that we could write a subclass. We even redefined one of the functions in our derived class. Now we will learn how to make the function behave virtually ''when called from'' C++. == Example == In this example, it is assumed that `hello::greet()` is a virtual member function: {{{ class hello { public: hello(const std::string& country) { this->country = country; } virtual std::string greet() const { return "Hello from " + country; } virtual ~hello(); // Good practice ... }; }}} We'll need a derived class<> to help us dispatch the call to Python. In our derived class, we need the following elements: 1. A Py``Object* data member (usually called `self`) that holds a pointer to the Python object corresponding to our C++ ''hello'' instance. 1. For each exposed constructor of the base class `T`, a constructor which takes the same parameters preceded by an initial Py``Object* argument. The initial argument should be stored in the `self` data member described above. 1. If the class being wrapped is ever returned ''by value'' from a wrapped function, be sure you do the same for the `T`'s copy constructor: you'll need a constructor taking arguments (Py``Object*, const T&). 1. An implementation of each virtual function you may wish to override in Python which uses {{{call_method(self, "name", args...)}}} to call the Python override. 1. For each non-pure virtual function meant to be overridable from Python, a static member function (or a free function) taking a reference or pointer to the `T` as the first parameter and which forwards any additional parameters neccessary to the default implementation of the virtual function. See below if the base class virtual function is private. {{{ struct hello_callback : hello { // hello constructor storing initial self parameter hello_callback(PyObject *p, const std::string& x) // 2 : hello(x), self(p) {} // In case hello is returned by-value from a wrapped function hello_callback(PyObject *p, const hello& x) // 3 : hello(x), self(p) {} // Override greet to call back into Python std::string greet() const // 4 { return call_method(self, "greet"); } // Supplies the default implementation of greet static std::string default_greet(const hello& self_) const // 5 { return self_.hello::greet(); } private: PyObject* self; // 1 }; }}} Finally, we add hello_callback to the `class_<>` declaration in our module initialization function, and when we define the function, we must tell Boost.Python about the ''default'' implementation: {{{ // Create the Python type object for our extension class class_ ("hello", init()) // Add a virtual member function .def("greet", &hello_callback::default_greet); }}} Now our Python subclass of `hello` behaves as expected: {{{ >>> class wordy(hello): ... def greet(self): ... return hello.greet(self) + ', where the weather is fine' ... >>> hi2 = wordy('Florida') >>> hi2.greet() 'Hello from Florida, where the weather is fine' >>> invite(hi2) 'Hello from Florida, where the weather is fine! Please come soon!' }}} <> == Pure Virtual Functions == A pure virtual function with no implementation is actually a lot easier to deal with than a virtual function with a default implementation. First of all, you obviously don't need to supply a default implementation. Secondly, you don't need to call ''def()'' on the `extension_class<>` instance for the virtual function. In fact, you wouldn't want to: if the corresponding attribute on the Python class stays undefined, you'll get an ''Attribute``Error'' in Python when you try to call the function, indicating that it should have been implemented. For example: {{{ #include #include #include #include #include #include using namespace boost::python; struct baz { virtual int pure(int) = 0; int calls_pure(int x) { return pure(x) + 1000; } }; struct baz_callback : baz { baz_callback(PyObject *p) : self(p) {} int pure(int x) { return call_method(self, "pure", x); } PyObject *self; }; BOOST_PYTHON_MODULE_INIT(foobar) { class_ >("baz") .def("calls_pure", &baz::calls_pure); } }}} Now in Python: {{{ >>> from foobar import baz >>> x = baz() >>> x.pure(1) Traceback (innermost last): File "", line 1, in ? AttributeError: pure >>> x.calls_pure(1) Traceback (innermost last): File "", line 1, in ? AttributeError: pure >>> class mumble(baz): ... def pure(self, x): return x + 1 ... >>> y = mumble() >>> y.pure(99) 100 >>> y.calls_pure(99) 1100 }}} == Private Non-Pure Virtual Functions == This is one area where some minor intrusiveness on the wrapped library is required. Once it has been overridden, the only way to call the base class implementation of a private virtual function is to make the derived class a friend of the base class. You didn't hear it from me, but most C++ implementations will allow you to change the declaration of the base class in this limited way without breaking binary compatibility (though it will certainly break the [[http://cs.calvin.edu/c++/C++Standard-Nov97/basic.html#basic.def.odr|ODR]]).