[C++-sig] call policies help needed
David Abrahams
dave at boost-consulting.com
Wed May 24 13:52:29 CEST 2006
"Roman Yakovenko" <roman.yakovenko at gmail.com> writes:
> Hi. Please consider next case:
>
> class A{ ... };
>
> struct B{
> B( A& a )
> : a( a )
> {}
>
> A& a;
> };
>
> In order to export class B, I have to create access function for
> member variable a.
>
> A& get_a( B& b ){ return b.a };
>
> BOOST_PYTHON_MODULE(module){
> class_< A > ...;
> class_< B >( "B", bp::init< A& >( )[with_custodian_and_ward<1,2>()] )
> .add_property( "a", make_funtion( &get_a, ???????? ) );
> }
>
> I don't know what call policies pyplusplus, code generator, should
> give for make_function
> by default. Why? Because there are different use case:
>
> 1. Python code:
> a = module.A()
> b = module.B( a )
> In this case life time of "a" is already managed by boost.python,
> so the return value
> policy for make_function could be "return_existing_object". I
> think, that in this case
> it is safe to use it.( Am I wrong ? )
It's safe until someone does
>>> del a
then b is dangling.
> 2. Python code:
> a = module.get_the_a_object() # returns reference to existing
> object a, that was created
> # from C++, life time
> of this object is not managed
> # by boost.python
> b = module.B( a )
> In this case it is unsafe to use "return_existing_object".
It's exactly as safe as in the previous case.
> The safer alternatives are:
>
> 1. to use "copy_[non]_const_reference",
That's safe from crashes.
> will not work for all classes, also
> this is not an expected behaviour:
> b.a.s = 2
> will not take effect, because b.a will return copy of a
Yes, that's the tradeoff.
> 2. to use "return_internal_reference". Here I make small
> assumption, that developer
> has some guaranties: object "a" will not be destroyed, if
> there is at least one "b"
> object.
No, it guarantees that the B Python object will not be destroyed as
long as there is at least one A Python object that has been
retrieved via
>>> b.a
> Obviously this guarantee exists in C++ code, but C++ code
> does not have garbage collector. In Python, object "b",
> could leave longer then object "a". So I am not sure about
> this option too.
>
> 3. "return_existing_object"
>
> 4. I am sure, I missed something.
In principle the C++ code has unsafety built into it, since a B object
can always outlive an A object. There's no safe choice with expected
behavior that you can derive merely by looking at C++ declarations;
you need to analyze the semantics of the C++ code, which might lead
you to discover that there's no way to get both safety and expected
behavior for this interface.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
More information about the Cplusplus-sig
mailing list