[C++-sig] Re: Iterators + shared_ptr + Abstract base classes + Pass by reference = help :)

David Sankel camio at yahoo.com
Mon Jan 6 21:05:07 CET 2003


Sorry about my garbled previous post.

--- "David Abrahams" <dave at boost-consulting.com>
wrote:
> > I would like the Python derived class to see a
> list of
> > Abstracts.  
> 
> And what do you expect it to be able to do to the
> list?  I'm not
> asking about the items it contains, yet.  Do you
> need to be able to
> modify the length of the list, or move items within
> it, etc?

I would like to have the ability to do everything that
you can do with a normal Python list.  Such as modify
the length, move items within it, etc.

> I don't see what iterators have to do with it.

That was my misunderstanding.

> Have you looked at
>
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/data_members.html
> ?
> 
> In order to use this, you'll need to expose the type
> of the
> Filter::data member.  Unless...
> 
> ...I suppose you want Filter::data to show up as a
> Python list also?

Yes, if possible.

> It sounds like you may want to explore
>
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/v2/faq.html#question2

Explored.  Thanks a lot for your help with this thus
far.  I really appreciate it.  Here is where I am now
(I'm using the container conversions pointed to by the
faq):

class Abstract
{
public:
  virtual shared_ptr<Abstract> clone()=0;
  virtual ~Abstract(){}
};

class Filter
{
public:
  vector<shared_ptr<Abstract> > data;
  virtual void doFilter( vector<shared_ptr<Abstract> >
&result)=0;
  virtual std::string name() const=0;
  virtual ~Filter(){}
};

class PythonFilter : public Filter
{
public:
  PythonFilter( PyObject * self )
    : m_self( self ), m_initialized(true) { };
    void doFilter( vector<shared_ptr<Abstract> >
&result)
    {
    if( m_initialized )
    {
      cout << "Got into doFilter with " << name() <<
endl;
      call_method< 
        void, 
        vector< shared_ptr< Abstract > > >
          ( m_self, "doFilter", ref( result ) );
    }
    }
  virtual std::string name() const
  {
    return call_method< std::string > ( m_self, "name"
);
  }
  virtual ~PythonFilter(){}
private:
  PyObject * m_self;
  bool m_initialized;
};

BOOST_PYTHON_MODULE(embedded_Filter)
{
  class_< 
    Abstract, 
    shared_ptr< Abstract >,
    boost::noncopyable > ("Abstract", no_init );

  class_< 
    Filter, 
    PythonFilter,
    boost::noncopyable > ("Filter");

  to_python_converter<
    vector< shared_ptr< Abstract > >,
   
scitbx::boost_python::container_conversions::to_tuple<
      vector< shared_ptr< Abstract > > > > ();

 
scitbx::boost_python::container_conversions::from_python_sequence<
    vector< shared_ptr< Abstract > >,
   
scitbx::boost_python::container_conversions::variable_capacity_policy>();

}

But I am still missing something because I cannot get
the following python code without the comments to
work:

from embedded_Filter import *
class SpecificFilter( Filter ):
  def name( self ):
    return 'SpecificFilterA'
  def doFilter( self, result ):
    print("In SpecificFilter.doFilter\n")
    print( len( self.data ) ) ; #self.data is a normal
python list
    print( len( result ) );     #So is result
    p = [x.clone() for x in self.data] #The members of
self.data can
                                        #have their
methods called
    result = p       #result can be modified as a
python list
    result.reverse() #another modification to result.

Thanks again for the help,

David J. Sankel
Head Consultant
Electron Consulting





More information about the Cplusplus-sig mailing list