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

Kun Hong kun.hong at uqconnect.edu.au
Thu May 20 15:03:41 CEST 2010


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.

=== test.cpp (wrapper and library code)

#include <boost/python.hpp>

using namespace boost::python;


class B
{
public:
	virtual const char *getName() const = 0;
};

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

const B& getB()
{
	static boost::shared_ptr<B> b(new C);
	
	return (*b.get());
}


BOOST_PYTHON_MODULE(Test)
{

	class_<B, boost::noncopyable>
	    ("B", no_init)
		.def("getName", pure_virtual(&B::getName))
	;
	
	def("getB", &getB, return_value_policy<reference_existing_object>());
}

=== main.cpp (C++ test code)

#include "test.h"

#include <algorithm>
#include <iostream>

using namespace std;

int main()
{
     printf("%s\n", getB().getName());
     return 0;
}

=== test.py (python test code utilize the C++ extension)

from Test import *

print getB().getName()



=== end

Using the above code, when I run test.py,  it gives the below error:

Traceback (most recent call last):
   File "test.py", line 3, in <module>
     getB().getName()
RuntimeError: Pure virtual function called


Then I tried changin this line
     	def("getB", &getB,  
return_value_policy<reference_existing_object>());
to:
         def("getB", &getB,  
return_value_policy<copy_const_reference>());


Then when I run test.py, the error becomes:

Traceback (most recent call last):
   File "test.py", line 3, in <module>
     getB().getName()
TypeError: No to_python (by-value) converter found for C++ type: B

What is the correct way to wrap this abstract class reference to the  
the polymorphic behavior?
Thanks in advance.

Kun



More information about the Cplusplus-sig mailing list