[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