More inheritance problems
Dear all, first of all thanks to Holger for pointing me to a workaround with the add_static_property problem! Unfortunately, I already ran into the next problem, which seems very weird to me: I have again my old friends Base and Derived, with the obvious inheritance (source file attached). Now, there is a third class, named "Third", which has as a data member a boost::shared_ptr<Base> which is initialized in the constructor. For this reason, the constructor takes such a pointer as an argument. Now, the point where stuff goes wrong is this: the argument to the constructor has as a default value a NULL-boost::shared_ptr<Base>. The behavior now works as expected if the argument is provided in python:
import testInheritance t = testInheritance.Third(testInheritance.Derived()) t.get_base().name() 'Derived'
However, this fails if one does not provide an argument:
t = testInheritance.Third() t.get_base().name() Traceback (most recent call last): File "<stdin>", line 1, in <module> Boost.Python.ArgumentError: Python argument types in Derived.name(Derived) did not match C++ signature: name(DerivedWrapper {lvalue}) name(DerivedWrapper {lvalue})
I cannot wrap my head around this, can anybody point me to what I am doing wrong? I would be very grateful! Best regards, Karl Bicker
t = testInheritance.Third(testInheritance.Derived()) her in reality an instance of DerivedWrapper is created, and then
Dear Karl, the problem is fixed if you do the following: bp::class_<BaseWrapper, boost::noncopyable>("Base", bp::no_init) .def("do_stuff", bp::pure_virtual(&BaseWrapper::do_stuff)) .def("name", &BaseWrapper::name, &BaseWrapper::default_name) .def("name", &Base::name) ; bp::class_<DerivedWrapper, bp::bases<Base> >("Derived") .def("do_stuff", &DerivedWrapper::do_stuff, &DerivedWrapper::default_do_stuff) .def("name", &DerivedWrapper::name, &DerivedWrapper::default_name) .def("name", &Derived::name) ; Note the two added definitions of `name`. Why is that needed? passed to C++. When you then do `t.get_base()` and instance of DerivedWrapper will be returned (there is actually some "magic" going on that boost python can associate your `boost::shared_ptr<Base>` with the PyObject that is a DerivedWrapper). Because that object is a `DerivedWrapper` the `.name` calls DerivedWrapper::name. In your second example the object is create with the call `_base = boost::shared_ptr<Base>(new Derived());`. This class is no subclass of `DerivedWrapper` nor `BaseWrapper`, so you can not call a member function of the wrappers. That is why you get the error. By exporting .def("name", &Base::name) you are able to call name if you have no Wrapper. The reason why you have to do .def("name", &DerivedWrapper::name, &DerivedWrapper::default_name) .def("name", &Derived::name) in the derived class is that the first definition overrides both definitions for `&BaseWrapper::name` and `&Base::name` -Holger On Tue, Sep 4, 2012 at 7:40 PM, Charly Bicker <legordian@gmx.net> wrote:
Dear all,
first of all thanks to Holger for pointing me to a workaround with the add_static_property problem!
Unfortunately, I already ran into the next problem, which seems very weird to me:
I have again my old friends Base and Derived, with the obvious inheritance (source file attached). Now, there is a third class, named "Third", which has as a data member a boost::shared_ptr<Base> which is initialized in the constructor. For this reason, the constructor takes such a pointer as an argument.
Now, the point where stuff goes wrong is this: the argument to the constructor has as a default value a NULL-boost::shared_ptr<Base>. The behavior now works as expected if the argument is provided in python:
import testInheritance t = testInheritance.Third(testInheritance.Derived()) t.get_base().name() 'Derived'
However, this fails if one does not provide an argument:
t = testInheritance.Third() t.get_base().name() Traceback (most recent call last): File "<stdin>", line 1, in <module> Boost.Python.ArgumentError: Python argument types in Derived.name(Derived) did not match C++ signature: name(DerivedWrapper {lvalue}) name(DerivedWrapper {lvalue})
I cannot wrap my head around this, can anybody point me to what I am doing wrong? I would be very grateful!
Best regards, Karl Bicker
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig
participants (2)
-
Charly Bicker -
Holger Brandsmeier