[C++-sig] Re: manage_new_object using release() instead of delete

Eric wstwej03 at sneakemail.com
Sat May 8 02:03:57 CEST 2004


This has worked like a charm, thanks very much.

In order to get it to work, I had do to two things which I thought might be
candidates for improvement.

The first is that I had to manually add some code to my BP initialization
file to create a class_value_wrapper for each type I wanted to use
shared_ptr with. Perhaps this is the kind of code that Pyste could be used
to auto-generate?

The second was that I had to use a special functor so that I could use a
member-function pointer instead of a void function pointer for the custom
delete. Both issues are illustrated below.

I wonder if there is also something like ReleaseFunctor below in boost for
use with shared_ptr...?

Consider these two classes:

// in MyClasses.h
class ClassOne {
public:
  void releaseOne() = 0;
};

class ClassTwo {
public:
  void releaseTwo() = 0;
};

typedef boost::shared_ptr<ClassOne> ClassOnePtr;
ClassOnePtr MakeClassOne();

// in boost_exports.cpp
template<class T>
class SharedPtrClassValueWrapper :
    public objects::class_value_wrapper<
        boost::shared_ptr<T>
      , objects::make_ptr_instance<T,
objects::pointer_holder<boost::shared_ptr<T>,T> >
    >
{
};

BOOST_PYTHON_MODULE(myclasses)
{
    SharedPtrClassValueWrapper<ClassOne>();
    SharedPtrClassValueWrapper<ClassTwo>();
    // etc.
}

// in myclasses.cpp
template<class T>
class ReleaseFunctor
{
  void (T::*releaseFunc_)();

 public:
  operator()( T * t ) {
    (t->*releaseFunc_)();
  }

  ReleaseFunctor(void (T::*rf)())
    : releaseFunc_(rf)
  {
  }
};


template<class T>
boost::shared_ptr<T>
MakeSharedPtr(T *y, void (T::*rf)())
{

  ReleaseFunctor<T> functor(rf);
  boost::shared_ptr<T> ret( y, functor );
  return ret;
}

ClassOne * MakeClassOne()
{
  return MakeSharedPtr( new ConcreteImpl(), &ClassOne::releaseOne );
}


-----Original Message-----
From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org]On
Behalf Of David Abrahams dave-at-boost-consulting.com |cppsig|
Sent: Tuesday, April 13, 2004 8:27 AM
To: eric.ries at aya.yale.edu
Subject: [C++-sig] Re: manage_new_object using release() instead of
delete


"Eric" <wstwej03 at sneakemail.com> writes:

> Hi all,
>
>
>
> I am new to Boost.Python, but so far have been extremely
> impressed. I was wondering if there was a version of the
> manage_new_object return policy that called a release() function on
> an interface rather than calling delete?
>
>
>
> I am trying to wrap a chunk of code that works like this:
>
>
>
> class Interface {
>
> public:
>
>   virtual void doSomething() = 0;
>
>   virtual void release() = 0;
>
> protected:
>
>   virtual ~Interface() {}
>
> };
>
>
>
> Interface *
>
> SomeFactory( ... );
>
>
>
> Now, if Interface was a normal data struct, I'd just use
> manage_new_object as the policy for SomeFactory, but that wouldn't
> work here because the destructor is protected. Is there some way to
> have the release function called at the end of the Interface
> pointer's life in python? And is it further possible to have the
> release() function not be callable from python (to protect against
> double-deletes)? Thanks!

Solution:

Put a thin wrapper around SomeFactory that builds a boost::shared_ptr
using a custom deleter that calls release(), and wrap that.

HTH,

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com


_______________________________________________
C++-sig mailing list
C++-sig at python.org
http://mail.python.org/mailman/listinfo/c++-sig







More information about the Cplusplus-sig mailing list