From: David Abrahams (abrahams_at_[hidden])
Date: 2001-01-19 23:19:05
----- Original Message -----
> I am using the latest CVS snapshot of boost.
> We are trying to define BPL Python bindings for some C++ classes that
> we are developing. In particular, we have a container class that
> manages a set of a polymorphic objects. I have distilled the idea down
> to a relatively simple example, dynatype.cpp. This file is available
> the boost egroup upload area:
> This simple python script shows what we want to do:
> import dynatype
> # Container with variables of a polymorphic type.
> c = dynatype.container() # <container object at 1400523a0>
> # Possible type identifiers are 'int' or 'double'.
> c.declare('int', 'an_int')
> c.declare('double', 'a_double')
> # Get references to the variables in the container.
> i = c.get('an_int') # <dynavalue_int object at 1400523f0>
> d = c.get('a_double') # <dynavalue_double object at 140052440>
> # Change the values of the variables.
> # Get them back (as Python integer or float).
> i.get() # 3
> d.get() # 3.1415
> # This proves that j.set() changes the contents of the container.
> j = c.get('an_int') # <dynavalue_int object at 1400523f0>
> j.get() # 3
> i.get() # 4
> This actually works, but there are a few issues:
> 0. Note that the values in the container are based on an abstract
> C++ class "dynabase."
> The actual values are C++ objects of the type "dynavalue<int>"
> and "dynavalue<double>."
This looks like a good place to take advantage of the "any" class template
which Kevlin Henney is currently preparing for release. The version which
passed the boost review process is at:
> The container is implemented using a
> std::map<string, boost::shared_ptr<dynabase> >
> 1. The Python c.get() is bound to the C++ function py_get().
> Somewhere inside this function we have to have a dynamic_cast<>()
> from a shared_ptr<dynabase>
> to a shared_ptr<dynavalue<int> >
> or a shared_ptr<dynavalue<double> >.
> To do this, I had to modifiy smart_ptr.hpp (line 139):
> template<typename Y>
> shared_ptr(const shared_ptr<Y>& r) : px(dynamic_cast<T*>(r.px))
> ++*(pn = r.pn);
> 1. Is there a better way of doing this?
I think that "any" could save you from this hack.
> 2. If not, would there be a way of having both the old and my
> modified copy constructor, and could this become part of
> the standard smart_ptr.hpp?
Sorry, I don't think so. Your version makes shared_ptr unusable with types
that don't have virtual functions. It also adds a reference count even when
r doesn't in fact point to a T, causing a leak.
> 2. There is a horrible memory leak associated with the use of c.get().
> I am pretty sure that this is due to the following invocation of
> boost::shared_ptr<dynavalue<int> > dvi(dv);
> return BOOST_PYTHON_CONVERSION::to_python(dvi);
> What is wrong with this use of to_python()?
Nothing, as far as I can tell, but you may be leaking due to your
modifications of shared_ptr.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk