[C++-sig] How to wrap reference to abstract base class to get C++ polymorphism

Kun Hong kun.hong at uqconnect.edu.au
Tue May 25 09:34:08 CEST 2010

On 20/05/2010, at 11:03 PM, Kun Hong wrote:

> Hi,
> I have a maybe entry-level question. But it really troubled me for a
> while.
> I need to wrap a C++ library which has some factory method to return
> references to some abstract base classes. So the implementation is
> hidden. If I want a python equivalent to the abstract base class
> reference type
> (so the polymorphism can work), how should I do it?
> Please see a very simplified example below which demonstrates what I
> mean.

Finally, I get to understand it and be able to answer my own question.
Post my own answer so future reader can get a pointer directly.

The answer is in the test code that comes with boost python library.
The code is in libs/python/test/polymorphism.{cpp,py}

I got my code working like below:

========== test.cpp ==========

#include <boost/python.hpp>

using namespace boost::python;

class B
     virtual const char *getName() const = 0;

     virtual int getValue() const
         return 10;

class C : public B
     virtual const char *getName() const
         return "Class C";


struct BWrap : public B
     BWrap(PyObject *self) : mSelf(self) {}
     PyObject *mSelf;

     const char *getName() const
         return call_method<const char *>(mSelf, "getName");

const B &getB()
     static boost::shared_ptr<B> b(new C);

     return (*b.get());


     class_<B, BWrap, boost::noncopyable> ("B", no_init)
         .def("getName", pure_virtual(&B::getName))
         .def("getValue", &B::getValue)

     class_<C, bases<B> >("C")
         .def("getName", &C::getName)

     def("getB", &getB,  

======== test.py =========
from Test import *

print getB().getName()
print getB().getValue()
c = C()
print c.getName()
print c.getValue()
#b = B()
#print b.getName()
#print b.getValue()

=== end

Not fully understand the pure_virtual call though, which doesn't  
prevent B
instance be created in python. "no_init" is needed for preventing B  

But, fun learning boost python, a lot to learn.


More information about the Cplusplus-sig mailing list