[C++-sig] Custodian and Ward doubts
Eric Jardim
ericjardim at gmail.com
Mon Sep 12 17:02:07 CEST 2005
Hi,
I have some questions about "custodian and ward" policy that are not very
clear on the docs.
Let's suppose we have a wrapped function "object* object::create(object*
parent)", where the parent is the custodian (holds a internal pointer to) of
the child, and we wrapped it correctly.
So, if in Python I do:
>>> a = create(None) # no parent
>>> b = create(a) # "a" is "b" parent and custodian
>>> del b # "b" is not deleted, because "a" is guarding it
>>> del a # no more refs, "a" and "b" are deleted
But what if I have another function "void object::setParent(object*
parent)", where the parent is changed. So, the new parent now is going to be
the custodian of the object.
>>> a = create(None)
>>> b = create(a)
>>> c = create(None)
>>> b.setParent(c) # c is the new parent (and should be the new custodian)
???
But what happens to the old parent (if it is not None)? Is it still a
custodian of the child? Can a child have more than one custodian? Or is it
like a ownership (only one is the custodian)?
I am asking it because I am having some problems with internal references
(pointers) from C++ objects to another that Python don't see. So I get many
objects being deleted prematurely, when they are actually being referenced
(in C++).
Other problem that I have, is that aside from some "a" object being parent
(custodian) of "b", internally, "a" deletes "b" and all of it's children
recursivelly. So Python's "b" waits for Python's "a" to be deleted, and "a"
is deleted in Python and C++. But with this C++'s "b" is deleted also, and
when Python is going to be deleted the pointer is dangled. So, In Python "a"
must die before "b", but in C++, "b" must die before "a". Now what?
The problem is that actually, both parent and child have references to each
other. But I cannot make circular custodian and ward, because they would
never get deleted.
I manage the problem by referencing objects in Python manually, but this
approach is not very interesting. Apart from this I can have C++ native (not
created by Boost.Python extended classes contructors), and also, if someone
may want to extend the library they would have to do a lot of dirty work.
I was thinking that implementing my custom call policies would be an elegant
and less error prone solution. Basically, every time a function return a
QObject pointer to Python, I use my custom return value policy, derived from
reference_existing_object. Internally, I can make a list of objects and
control when they must die. But I am afraid if this is the best solution.
Does anybody have a problem like this? Which solution do you sugest?
Thanks,
[Eric Jardim]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20050912/179b1970/attachment.htm>
More information about the Cplusplus-sig
mailing list