[C++-sig] Re: Inheritance with B/P
David Abrahams
dave at boost-consulting.com
Tue Feb 11 01:54:22 CET 2003
Bruce Lowery <bruce_lowery at yahoo.com> writes:
> --- David Abrahams <dave at boost-consulting.com> wrote:
>> Bruce Lowery <bruce_lowery at yahoo.com> writes:
>>
>> >> > Is there a better way to do this?
>> >>
>> >> Does
>> >>
>> >> implicitly_convertible<
>> >> std::auto_ptr<Derived>
>> >> , std::auto_ptr<Base>
>> >> >();
>> >>
>> >> , placed in your module init function, help?
>> >>
>> >
>> > Although this would be an improvement over what I'm doing now, it still
>> > requires a 'implicitly_convertible' for each derived class, doesn't it?
>>
>> Yep. I could try to create auto_ptr conversions automatically, but
>> the system is designed to work on all kinds of smart pointer and
>> generalizing the mechanism would be very difficult. Maybe I shouldn't
>> worry about that.
>>
>
>
> Perhaps a better way is to avoid the use of auto_ptr altogether.
> Recall that I needed to use it because I'm wrapping some methods
> that take ownership of a passed-in pointer. Is it possible to
> invent a new policy to represent this semantic information and that
> would cause b/p to set 'thisown=0' on the python object wrapping the
> pointer?
I don't think it's possible without replicating the same work as I
detailed above. There is basically only one way a pointer ever gets
wrapped "raw", with no expectation that the referent's lifetime is
tied to that of a Python object, and that's when you use
reference_existing_object.
The _only_ way a Python object holds a pointer whose ownership it can
"give away" to your wrapped function, is when it holds that pointer by
auto_ptr.
Now, it's easy enough to find out that there is a Base* in the object,
even when the object holds an auto_ptr<Derived>. The problem is
getting the object to release ownership. To do that, I have to
somehow talk to the auto_ptr<Derived> object, i.e. to call its
release() function, or to copy it into an auto_ptr<Base> object.
I guess one possibility would be to hold owned pointers not by
auto_ptr, but by something like this:
struct owner_base
{
owner_base(void* p) : m_p(p) {}
void* release() { void* p = m_p; m_p = 0; return p; }
void* get() const { return m_p; }
private
void* m_p;
};
template <class T>
struct owner : owner_base
{
owner(T* p) : owner_base(p) {}
~owner() { delete get(); }
T* get() const { return static_cast<T*>(this->owner_base::get()); }
private:
void operator=(owner const&);
owner(owner const&);
};
Then once you know there's a Base* and an owner_base in the object you
can ask the owner_base to release(). Whew, it's complicated, though.
Further, call policies don't currently control how conversions occur;
the stuff that handles ownership is currently just working on Python
objects in precall() and postcall() routines (look it up; you'll see
what I mean). This looks like an achievable but difficult
modification; not one I can see having time to do in the near future
as long as I have other paying work I can do ;-)
It looks like it would be easier to get the auto_ptr thing working,
though I realize that's not an ideal solution for you.
Sorry,
Dave
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
More information about the Cplusplus-sig
mailing list