[C++-sig] Support for virtual functions with default implementations
David Abrahams
dave at boost-consulting.com
Wed Nov 27 07:57:53 CET 2002
Some of you have been struggling with a supposed inability of
Boost.Python v2 to correctly expose virtual functions with default
implementations. You can read all about the nitty-gritty details at:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/polymorphism.txt
The bottom line, when exposing a class B with its "callback" class
Bcb...
struct B
{
virtual std::string f() { return "B"; }
};
struct BWrap : B
{
BWrap(PyObject* self) : m_self(self) {}
virtual std::string f()
{
return call_method<std::string>(m_self, "f");
}
std::string f_default()
{
return B::f();
}
PyObject* m_self;
};
...turns out to be that sometimes, from Python, B.f() must invoke B::f
virtually (e.g. when the Python object actually holds a [smart]
pointer to some C++ class derived from B), and sometimes it must
invoke BWrap::f_default, which invokes the actual B::f defined in B.
Well, after several weeks of working on a complicated solution to this
problem, I had an Aha! moment, and realized that we already had the
capability!** The key is simply to expose your class like this:
class_<B, BWrap // or, e.g., shared_ptr<BWrap>
>("B")
.def("f", &B::f) // dispatch function
.def("f", &BWrap::f_default) // default implementation
;
That's it! Because later def() overloads get precedence, your default
implementation will be used if the Python object actually contains a
BWrap object. Otherwise, it will call B::f virtually.
Issues:
1. f_default MUST be a member function of BWrap, or take a BWrap&
first argument
2. You MUST def() f_default second.
Failure to get either of these right will result in crashes or other
runtime failures.
I have just checked in changes which allow you to supply your default
implementation in the .def() invocation:
.def("f", &B::f, &BWrap::f_default)
This version will catch those potential errors at
compile-time. However, the other version should work fine with the
Boost 1.29.0 release.
-Dave
**Don't worry, the weeks weren't a complete waste; the code got a lot
cleaner as I refactored things.
--
David Abrahams
dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution
More information about the Cplusplus-sig
mailing list