[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