[C++-sig] Re: (no subject)

Raoul Gough RaoulGough at yahoo.co.uk
Mon Sep 29 17:19:57 CEST 2003


David Abrahams <dave at boost-consulting.com> writes:

> Raoul Gough <RaoulGough at yahoo.co.uk> writes:
>
>> Also, if you want to manage Python objects in C++, the Boost.Python
>> library has some code to help with the reference count management,
>> mostly in the "object" class. Maybe grepping for the (undocumented?)
>> borrowed_reference or new_reference in the libs/python/src tree will
>> provide suitable examples?
>
> Uhm.  Those are really not for user consumption, which is why they're
> not in namespace boost::python::.

Oh, OK. I should have been using this all along. That's what I get for
learning from the implementation code instead of reading the
documentation!

> I'm not sure it was the right choice, but users are supposed to go
> through handle<> to acquire references.  Either:
>
> handle<> x(whatever);   // new reference
> handle<> x(borrowed(whatever));  // borrowed reference
>
> object(x); // now we have an object.

Well this interface seems OK to me. If anything is wrong with it,
maybe it would be safer not to accept plain pointers, and require
something like new_reference<T> for new references. This would force
the user to make the decision explicitly, rather than possibly getting
it by mistake.

BTW, does this work without partial template specialization support?

> I've been thinking a bit about this interface recently.  I think
> something like the following might be better:
>
>      class reference 
>      {
>       public:
>          PyObject* get() const;
>          ...
>       protected:
>          reference(PyObject*);
>          reference();
>       private:
>          void operator delete(void*); // not defined
>          void operator delete(void*, size_t);
>      };
>
>      class borrowed_reference : reference
>      {
>       public:
>          borrowed_reference(PyObject*);
>      };
>      
>      class new_reference : reference
>      {
>       public:
>          new_reference(PyObject*);
>      };
>      
> This allows python::references to be passed around, but not
> constructed.  You have to say borrowed_reference or new_reference
> explicitly.

Using this approach would cause me to worry about object slicing (C++
object slicing, I mean) since I would probably tend to pass and
certainly return reference objects by value. I suppose the base class
would actually be equipped to handle everything internally, but I
would *usually* assume that the following code is wrong:

reference make_python_object () {
  return new_reference (/*...*/);  // Slices object on return
}

The overloaded constructor approach has the advantage that it makes it
clear that the type of the constructed object is the same whatever the
original source of the raw pointer.

-- 
Raoul Gough.
(setq dabbrev-case-fold-search nil)





More information about the Cplusplus-sig mailing list