[C++-sig] polymorphic object handling

David Abrahams dave at boost-consulting.com
Tue Aug 9 20:32:27 CEST 2005


Burkhard Doliwa <doliwa at temf.tu-darmstadt.de> writes:

> Hi all,
>
> I have a problem wrapping a factory function to python. I have two 
> abstract base classes A,B, with some child classes
>
> A<-A1,A2,A3
> B<-B1,B2,B3
>
> every child class is either able to clone itself or to return an 
> instance of the corresponding "parallel class", i.e.
>
> A* A1::cloneA() const	yields an A1
> B* A1::cloneB() const	yields an B1
>
> A* B2::cloneA() const	yields an A2
> B* B2::cloneB() const	yields an B2
>
> and so forth. The factory function
>
> object factoryA(const A&, bool isA) {
> 	return isA? object(A.cloneA()) : object(A.cloneB());
> }
>
> only returns python objects of the base class types, not the derived 
> classes, i.e.
>
>  >>> a1=A1()
>  >>> factory(a1,True)
> result=  A object (NOT an A1 object)
>
> How could I create the correct derived class in such a conditional 
> factory function (like the return_value_policy<manage_new_object>() case)?

You might consider:

    template <class T>
    T* owned(T* x) { return x; }

  object factoryA(const A&, bool isA) {
	return isA? 
      make_function(
          &owned<A*>, return_value_policy<manage_new_object>()
      )(ptr(A.cloneA()))

      : make_function(
          &owned<B*>, return_value_policy<manage_new_object>()
      )(ptr(A.cloneB()))
    ;
  }

However, a more principled approach would have the cloneX functions
return an auto_ptr<X> and then do 

       register_ptr_to_python<auto_ptr<X> >()

Then you can leave factoryA as it was.
  
-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com




More information about the Cplusplus-sig mailing list