[C++-sig] Re: Containers for derived classes

abeyer at uni-osnabrueck.de abeyer at uni-osnabrueck.de
Wed Aug 6 16:58:26 CEST 2003


>> However, the FAQ says there are more elegant ways by using
>> boost::shared_ptr:
>> "When a shared_ptr<X> is converted back to Python, the library checks to
>> see if it's one of those "Python object managers" and if so just returns
>> the original Python object."
>>
>> I have played with it, but I had no luck so far.
>
>What did you do?  Please post some code which illustrates.
>
>> Has anyone an example using shared_ptr that fits my purpose?
>
>If you make C a container of shared_ptr<A>, it should just work.

OK, this is what I have tried:

--- begin ptr_test.cpp

#include <boost/shared_ptr.hpp>
#include <boost/python.hpp>

using namespace boost;

class A {
     public:
	A(int i) : val(i) { }
	int val;
};
typedef shared_ptr<A> A_ptr;

class C {
     public:
	void set(A_ptr& a) { this->a=a; }
	A_ptr& get() { return this->a; }
     private:
	 A_ptr a;
};

BOOST_PYTHON_MODULE(ptr_test)
{
    using namespace boost::python;
    class_<A>("A", init< int >() )
	.def_readwrite("val", &A::val)
    ;
    class_<C>("C", init< >() )
	.def("set", &C::set, with_custodian_and_ward<1, 2>())
        .def("get", &C::get, return_internal_reference<>() )
    ;
}
--- end ptr_test.cpp

This code raises a TypeError in Python:

>>> from ptr_test import *
>>> a=A(0)
>>> c=C()
>>> c.set(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: bad argument type for built-in operation

I can change the module definition for class A to:

// ...
    class_<A, A_ptr>("A", init< int >() )
	.def_readwrite("val", &A::val)
    ;
// ...

Then I get the following:
>>> from ptr_test import *
>>> a=A(0)
>>> c=C()
>>> c.set(a)
>>> a1=c.get()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: No Python class registered for C++ class N5boost10shared_ptrI1AEE







More information about the Cplusplus-sig mailing list