[C++-sig] pointer_holder and pure virtual base classes

Allen Bierbaum abierbaum at gmail.com
Sat Oct 28 00:57:55 CEST 2006


Sorry to reply to an old e-mail, but I just got time to revisit this
issue.  See below...

On 9/19/06, Roman Yakovenko <roman.yakovenko at gmail.com> wrote:
> On 9/19/06, Allen Bierbaum <abierbaum at gmail.com> wrote:
> > This is a followup to my efforts in the thread here:
> > http://thread.gmane.org/gmane.comp.python.c++/10125/focus=10125
> >
> > I seemed to have everything working but I just ran into a new problem.
> >  A simplified summary is:
> >
> > class Base
> > {
> > public:
> >    int getSomething() = 0;
> > };
> >
> > class DerivedA : public Base
> > {
> > public:
> >    int getSomething() { return 1; }
> > }
> >
> > class DerivedB : public DerivedA
> > {
> > public:
> >    int getSomething() { return 1; }
> > }
> >
> > I am wrapping these classes with a held_type of RefPtr<classType>
> > except for the Base class because it is pure virtual.  (this is a
> > custom ref counting pointer; see thread above for details)
> >
> > I thought everything was good until I tried to wrap a factory class.
> > The class can return any class type but it returns it through a
> > pointer to the Base class like this:
> >
> > class Store
> > {
> > public:
> >    RefPtr<Base>  getObject(int id);
> > };
> >
> > The problem wrapping this is that since I do not have a held_type
> > registered for the base type as RefPtr<Base>, there is no to_python
> > (by-value) converter found for C++ type: RefPtr<Base>.
> >
> > As an attempt to fix this I set the held type for Base to
> > RefPtr<Base>, but this fails because pointer_holder.hpp line 179 needs
> > to be able to alloate an object of the pointee type.  Since it is pure
> > virtual the compiler fails here.
> >
> > So my question is, when dealing with a polymorphic hierarchy like this
> > is is possible to use a smart pointer as a held type for the most
> > basic types?  (ie. the pure virtual base).  If not, does anyone have
> > suggested workarounds for me to try?
>
> David Abrahams solved this problem for my case. See "custom smart pointer"
> thread.
>
> Basically you will have to set as HeldType RefPtr<BaseWrapper>, where
> BaseWrapper is a wrapper class, that defines "override" for pure
> virtual functions.

Unfortunately I can't do this. The smart pointers I am using are not
quite standard, so I can't apply them easily to the wrapper. I did
find another way to do it though that almost works...


> Your smart pointer shoud support construction of RefPtr<Base> from
> RefPtr<Derived>.


What I did was register a ptr_to_python for my base class RefPtr type.
I also already had a to_python_converter registered for the type
returned from the store (an FCPtr). So now with the ptr_to_python
registered the path boost.python should be taking is:

- I call the getObject method of the store which returns a FCPtr<Base>
- A custom to_python converter gets called with returns a
RefPtr<FcPtr<Base> >: "return
bp::incref(bp::object(RefPtrType(fcPtr)).ptr());"
- boost.python recognizes this type as a ptr because of a call I make
to bp::register_ptr_to_python<RefPtr<FcPtr<Base> > >();

This all seems to work but I get a very strange error when trying to
use an object returned through this path. Here is a sample run:

>>> n = osg2.Node.create()
>>> osg2.FieldContainerFactory.the().getContainer(osg2.getContainerId(n))
<osg2._osg2.Node object at 0xb77eff2c>
>>> n2 = osg2.FieldContainerFactory.the().getContainer(191)
>>> n
<osg2._osg2.Node object at 0xb77ef1ec>
>>> n2
<osg2._osg2.Node object at 0xb77ef36c>
>>> n.getType()
<osg2._osg2.FieldContainerType object at 0xb7590ae4>
>>> n2.getType()
Traceback (most recent call last):
File "<input>", line 1, in ?
ArgumentError: Python argument types in
Node.getType(Node)
did not match C++ signature:
getType(OSG::Node {lvalue})
getType(OSG::Node {lvalue})

As you can see, the n2 variable type looks like it converted to the
correct type but it doesn't work. Does anyone have any ideas what I
should be looking for here? Any ideas how I can trace it down?

Thanks,
Allen



More information about the Cplusplus-sig mailing list