[C++-sig] newbie: create shared_ptr to self within python

Andreas pirx at cs.tu-berlin.de
Sun Jan 23 00:44:36 CET 2005


hello,

I have a problem with conversion of python class instances to shared_ptr 
within python.
I defined an abstract base class in c++ that is used in c++ and in 
embedded python. Only shared_ptr to the concrete instances should be 
useable. Thus the concrete classes have hidden ctor's. They must provide 
a factory method for creating. Copying of an object must be done using a 
clone method.
In detail there are two problems:
1. Create a shared_ptr to a new class instance by using a class factory
    method
2. Clone a python class instance and return a shared_ptr to the new
    instance

The example code:
//in c++
class Base
{
   public:
     virtual ~Base() {}
     virtual shared_ptr<Base> clone() const = 0;
     virtual std::string name() const = 0;

   protected:
     Base() {}
};

void whoiam(shared_ptr<Base> pBase) { std::cout << pBase->name(); }

//in this example there is no need for class DerivedA. That's only for
// better explanation of the context described above.
class DerivedA : public Base
{
   public:
     static shared_ptr<DerivedA> create(int n)
     { return shared_ptr<DerivedA>(new DerivedA(n)); }

     virtual shared_ptr<Base> clone() const
     { return shared_ptr<DerivedA>(new DerivedA(*this)); }

     virtual std::string name() const { return "derivedA"; }

   protected:
     DerivedA(int n) : _n(n) {}
     DerivedA(const DerivedA& other) : _n(other._n) {}

   private:
     int _n;
};

//wrapping base
struct BaseWrapper : public Base, wrapper<Base>
{
   shared_ptr<Base> clone() const {return this->get_override("clone")();}
   std::string name() const { return this->get_override("name")(); }
};

//export
BOOST_PYTHON_MODULE(test)
{
   def("whoiam", &whoiam);

   class_<BaseWrapper, shared_ptr<BaseWrapper>, noncopyable>("Base", 		
     no_init)
     .def("clone", pure_virtual(&Base::clone))
     .def("name", pure_virtual(&Base::name))
   ;
}

//in python
from test import *

class DerivedB(Base):
     def __init__(self, data):
         self.__data = data

     @staticmethod
     def create(data):
         return DerivedB(data)

     def copy(self):
         return self

     def name(self):
         return 'derivedB'


b = DerivedB.create('somestring')
whoiam(b)
bCopied = b.copy()
whoiam(bCopied)

Here is the result of the interpreter for both whoiam lines:
whoiam(b)
Boost.Python.ArgumentError: Python argument types in
whoiam(DerivedB)
did not match C++ signature:
whoiam(class boost::shared_ptr<class Base>)

How can i define/register an converter which does such an implicit 
conversion?
(I'm using Boost 1.32.0, MSVC7.1 and Python 2.4)

Thanks a lot for any help,
andreas



More information about the Cplusplus-sig mailing list