[C++-sig] Instance ownership transfer in constructor.

Holger Brandsmeier brandsmeier at gmx.de
Thu Jul 5 19:44:54 CEST 2012


Jani,

ok what you want to do is quite a lot more intrusive, so you need some
more involved methods, but it should be possible. I would do it by
noting the following
 - data_1 is published to python as a boost::shared_ptr<Data> (default
holder type)
 - usually it is difficult for a class member function, to obtain a
shared_ptr<> to itself, i.e. something like `this` but not of type
Data* but of boost::shared_ptr<Data>.
 - fortunately there is something supported by boost itself, called
`enable_shared_from_this`, see
  http://stackoverflow.com/questions/142391/getting-a-boostshared-ptr-for-this
 - Now you want `owner` to hold on to this `shared_ptr<Data>` which
ensures that `data_1` does not get deleted before `owner`, you can do
this by
  owner->setData( shared_from_this() )
in any member function of `Data`.
 - Note that I _think_ that you are not allowed to use
`shared_from_this()` in the constructor itself, so you might have to
use boost::pythons `make_constructor` to make an ordinary member /
non-member function behave as the constructor in python.

Maybe someone has a quicker way of doing this, but remember that this
is exactly the use case that `shared_ptr` are made for,
Holger


On Thu, Jul 5, 2012 at 6:47 PM, Jani Tiainen <redetin at gmail.com> wrote:
> I want to do it another way around:
>
> Instance of Owner should hold reference to data_1 and data_2 as long as
> owner is alive.
>
> Now following happens:
> owner = Owner()
> data_1 = Data(owner) # data_1 ownership is transferred to owner object
> data_2 = Data(owner) # data_2 ownership is transferred to owner object
>
> print owner.get_data_objects()
>
> <data_1>, <data_2>
>
> del data_1
> del data_2
>
> print owner.get_data_objects()
> # Crash because data_1 and data_2 are deleted even owner should still hold
> the reference.
>
> I tried to do it like
> http://www.boost.org/doc/libs/1_49_0/libs/python/test/injected.cpp  but it
> didn't worked for me.
>
>
> On Thu, Jul 5, 2012 at 7:00 PM, John Reid <j.reid at mail.cryst.bbk.ac.uk>
> wrote:
>>
>> On 05/07/12 11:49, Jani Tiainen wrote:
>> > Hi,
>> >
>> > I'm new to python.boost library and I'm trying to use it to wrap a third
>> > party library. Everything else I've managed to get working - thanks to
>> > excellent library and lot of examples I've found around a net.
>> >
>> > Only thing I can't get working properly is instance ownership transfer
>> > in constructor.
>> >
>> > So classes in library are defined like follows:
>> >
>> > class Owner {
>> > ...
>> > }
>> >
>> > class Data {
>> >     Data(Owner *owner); // <-- Here happens ownership transfer.
>> > }
>> >
>> >
>> > Python code is like follows:
>> >
>> > owner = Owner()
>> > data_1 = Data(owner)
>> > data_2 = Data(owner)
>> >
>> > So when Python script stops runnning it causes crash due the fact that
>> > I've data objects are automatically destroyed by Owner-class but Python
>> > deletes them by using Data-class destructor (which shouldn't happen
>> > ever).
>> >
>>
>> If I understand you correctly then you want the owner object to remain
>> alive at least as long as data_1 and data_2? If so you could use
>> with_custodian_and_ward:
>>
>> http://www.boost.org/doc/libs/1_49_0/libs/python/doc/v2/with_custodian_and_ward.html
>>
>> For example something like the following should work:
>>
>>         namespace py = boost::python;
>>         py::class_<
>>                 ...
>>         > my_class(
>>             "Data",
>>             "docstring.",
>>             py::init< Owner * >( "Constructor." )[
>>                 py::with_custodian_and_ward< 1, 2 >()
>>             ]
>>         );
>>
>> _______________________________________________
>> Cplusplus-sig mailing list
>> Cplusplus-sig at python.org
>> http://mail.python.org/mailman/listinfo/cplusplus-sig
>
>
>
>
> --
> Jani Tiainen
>
> - Well planned is half done, and a half done has been sufficient before...
>
>
> _______________________________________________
> Cplusplus-sig mailing list
> Cplusplus-sig at python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig


More information about the Cplusplus-sig mailing list