The right way to expose a complex short-lived object

I am developing Darwinian evolutionary modeling. For performance reasons, it is written in C ++. The sim is represented by an instance of World. Animals are represented by instances of Animal, a rather complex object. There are two important methods in the world:

animal_at(int i) 

and

 evolve(int n). 

animal_at returns a non-zero raw pointer to an instance of Animal that represents the ith animal.
evolution advances the simulation, possibly invalidating any pointer returned by animal_at . I want to make sim and animals easily accessible from the outside. I have python-specific bindings, but I'm considering training CORBA or Ice to implement a more universal interface. The problem is how I should exhibit animals. I have two ideas, none of which seem satisfactory: 1) Rewrite the code a bit to use shared_ptr instead of raw ptr and use middleware that understands the semantics of shared_ptr. 2) Create a "deep lazy proxy" that has the same structure as Animal. Its members will be recursively proxy sites for Animal members. animal_at will actually be called at the last moment before referring to the actual data - the pointer will be used and immediately discarded. This would provide the semantics of the "last moment".

I don’t like 1) because I will need to enter the “zombie” state of the object, which seems illogical to me. I do not like 2) because the sole purpose of the proxy server is to implement the "last moment" semantics.

I am looking for an automatic non-intrusive way (using code generation) to achieve this, because I do not want to hide the meaning of the source code. Is there any “official” name for the “last moment” semantics?

+7
source share
4 answers

There is an option to use boost :: weak_ptr. You can pass them, they must use lock () to get the underlying shared_ptr so that they can see that the object no longer exists.

The lifetime of an object is determined only by the places where shared_ptr is stored. Therefore, during the lifetime of an object, there must be at least one of them, and you need it before you can create weak_ptr.

+2
source

First, you can consider xml-rpc instead of CORBA as middleware (more standard use at the moment).

Secondly, external users work with sorted data. They send a focused link to the middleware and expect generalized information based on their request and link, so I don’t see how this works with semantics and “last-minute” pointers. You either keep all your temporary animals, so external users may request them, or you may have to send a lot of exceptions due to animals not found. (or you allow them to ask for the "last" animal)

+1
source

If your animal_at function returns a pointer that may be invalid at any time in the future, you can try to return a smart pointer to them (I would suggest shared_ptr over weak_ptr here, but you can leave with a weak pointer if you are careful with the implementation). However, instead of pointing directly to the Animal object, specify a boost::optional<Animal> object. Thus, when you reject a pointer, you can set the invalid flag in the pointer, and any user of a new invalid object has the opportunity to check whether they need to get a new pointer.

+1
source

I don’t understand why you want to export the pointer instead of exporting the interface, which, apparently, you need in the semantics of the last moment. Your animal_at can return the identifier of the object, not a pointer, and the interface will provide all the necessary access to the object, for example dosomething(id, params) . The interface may also include a lock / unlock to allow atom access.

+1
source

All Articles