Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The right way to expose a complex short-lived object

I am developing a Darwinian evolution simulation. For performance reasons, it's written in C++. The sim is represented by an instance of World. The animals are represented by instances of Animal, a fairly complicated object. World has two important methods:

animal_at(int i) 

and

evolve(int n). 

animal_at returns a non-null raw pointer to the instance of Animal that represents the i-th animal.
evolve advances the simulation possibly invalidating any pointer returned by animal_at. I want to make the sim and the animals easily accessible from outside. I have python-specific bindings, but i'm considering learning CORBA or Ice to implement a more generic interface. The problem is how I should expose the animals. I have two ideas, none of which feels satisfactory: 1) Rewrite the code slightly to use shared_ptr instead of a raw ptr and use a middleware that understands shared_ptr semantics. 2) Generate a "deep lazy proxy" that has the same structure as Animal. Its members would be proxies to members of Animal, recursively. animal_at would be actually called in the last moment before referring to the actual data -- the pointer would be used and immediately tossed away. This would implement the "last moment" semantics.

I dislike 1) because I would have to introduce a "zombie" state of the object, which looks inelegant to me. I dislike 2) because the sole purpose of the proxy is to implement the "last moment" semantics.

I am looking for an automatic non-intrusive way (using code-generation) to achieve this, because I don't want to obscure the meaning of the original code. Is there any "official" name for what I call "last moment" semantics?

like image 313
Pavel Bazant Avatar asked Jan 04 '11 14:01

Pavel Bazant


2 Answers

There is an option of using boost::weak_ptr. You can pass these around, they have to use lock() to get the underlying shared_ptr so they can see if the object no longer exists.

The lifetime of the object is determined only by the places where a shared_ptr is held. There must therefore be at least one of these at all times during the lifetime of the object, and you need one before you can create a weak_ptr.

like image 144
CashCow Avatar answered Sep 28 '22 17:09

CashCow


Firstly, you might consider xml-rpc instead of CORBA as middleware (more standard use nowadays).

Secondly, external users work with marshalled data. They send a marshalled reference over the middleware and expect marshalled information based on their request and reference, so I don't see how this works together with "last moment" sementics and pointers. You either keep all your temporary animals, so external users can query them or you probably have to send a lot exceptions for not found animals. (or you let them request the "latest" animal)

like image 27
stefaanv Avatar answered Sep 28 '22 18:09

stefaanv