Objetos a los que se hace referencia en varias ubicaciones

I am trying to figure out how to manage items in my program. I want to have a unified inventory system that knows where every item is. Then have container objects that actually hold the inventoried items, and have everything locate-able by container ID.

My thought was to have items held inside the containers dentro boost::ptr_vetors, and then hold a pointer (probably the same one) inside a hash table inside the inventory object, now shifting things around in terms of the inventory is easy that just changing a single value, and moving things from containerX to containerY is just a matter of removing from one pointer vector, and passing it to the other container, or doing all the work in one container, u otro.

The problem that I am having trouble considering is when it comes time to get all the stuff out. I have only really ever dealt with having a pointer/object held in one place at a time not multiple, and I know that if I try to delete something that has already been deleted it will cause a crash at the least. The first thing that comes to mind is to remove all the references from the containers, and still have it reside in the inventory, and then step through, and delete the inventory. Is this feasible, or am I not considering this right, and need to reconsider this? then what if I only need to remove a single thing (keep the rest)?

I am concerned about de-validating the pointers in either case.

preguntado el 03 de mayo de 12 a las 08:05

Why not use a vector of smart pointers (in C++11 or with Boost)? you won't have to care about whether or not you have to delete your pointer anymore. But I'm not sure to have understood your problem... -

2 Respuestas

Boost::ptr_vector assumes ownership of the object when you pass it in. When you remove an object from that vector it will be automatically deleted. You can remove items without deleting them however by using the built in auto_type (see the farm yard example for usage).

This means that you should really only have an item in one ptr_vector at a time. However your idea of having items in a ptr_vector y luego tener la ptr_vector be owned by your inventory object (which is another ptr_vector) should work. I have never done that but it should be fine.

In order to delete a single object you just look it up using a container_id and an item_id, and then remove it from the item-level ptr_vector. In order to delete a container, just remove it from the inventory. It will destruct anything that it contains at that point.

If you want to remove them without deletion use the auto_type to remove them safely. You can release them from the auto_type and do as you please if you want to using raw pointers to objects.

contestado el 03 de mayo de 12 a las 09:05

Hay algunas formas de hacer esto.

  1. Utiliza boost::shared_ptr or std::shared_ptr with the standard vector. That way you do not have to worry about deleting and memory is freed incrementally whenever no pointer references the object. This can be useful if you need to destroy specific objects frequently and requires the least amount of code. The downside is storage overhead if most objects are never destroyed apart from the rest and you have a lot of objects. And, depending on where you remove the object, it can still reside in the inventory without a container or vice versa.
  2. Give the containers responsibility for destruction and deindexing from the inventories by deriving them or wrapping them in another class. Since each object's pointer only appears in one container as described by you, only inventories may hold extra pointers. Hence whenever an object is to be removed, the container will have to look up the inventories to remove the pointer to the object it is about to destroy. The overhead is the bookkeeping of the inventories.
  3. Use a memory pool that is a container that stores pointers to all objects and is responsible for their destruction when itself is destroyed. The memory pool can be a boost::ptr_vector while the other containers are standard vectors. This effective for frequent adding and querying objects in the system. The downside is that the memory pool must outlive your containers and inventories. Otherwise it has to do bookkeeping like in (2) if individual objects need to be destroyed apart from the rest.

contestado el 03 de mayo de 12 a las 09:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.