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

David Abrahams dave at boost-consulting.com
Mon Sep 29 17:47:09 CEST 2003


Raoul Gough <RaoulGough at yahoo.co.uk> writes:

> 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?

Of course.

>> 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
> }

There's nothing wrong with "slicing".  Its dangers are vastly
overrated.  Think of it as an implicit conversion operator.

> 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.

Well, my point was that I thought it was more useful and safer to
encode the acquisition method in the type.

Could be wrong, though.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com





More information about the Cplusplus-sig mailing list