Question

I have a small hierarchy of classes and I'm trying to figure out a simple way of maintaining ownership. Since these objects are residing on the heap and since I hate raw pointers, I figure I'll use boost shared and weak pointers. (I'm open to alternatives, but it's what I'm used to.) Shared pointers can help with ownership, since a weak pointer won't prevent an object from being deleted when the owner of the shared pointer says so.

The hierarchy:

class Actor;
class Body : public virtual Actor;
class Owned : public virtual Actor;
class Combatant : public Body, public Owned;

There's some other classes there, too. I can deal with the diamond inheritance using virtual inheritance, so that's not a big deal. Also, I'll typedef some shared_ptrs and weak_ptrs for each of them.

My idea is to have Actor maintain a static list of Actor shared pointers (ActorPTR), and have the children classes maintain static lists of weak pointers (BodyWPTR, etc.) This way there's one definitive collection of shared pointers, so that should manage some sort of ownership (I'll try not to permanently store shared pointers anywhere else.) Having these lists is handy because I can quickly say, "get me all the combatants nearby" or "move all bodies."

I'd like the objects to insert themselves into the proper lists: a Body would insert a weak pointer of itself into the body weak pointers list, and it would insert an Actor shared pointer into that list, possibly done in the constructor. BUT (apparently) it's bad mojo to use the "this" pointer (or it's shared_from_this() equivalent) in a constructor. The only other way I can think of doing it is through a whole bunch of factory methods. I also figure it's bad to have multiple classes in the hierarchy inherit from enable_shared_from_this.

How do I have an object automatically insert a shared or weak pointer to itself into a list during its constructor? Is that a bad idea?

(Also in the "code" above, I may have messed up the virtual inheritance syntax but that's not what I'm concerned about right now, so don't worry about that.)

Thanks!

Was it helpful?

Solution

You can use just one factory method using a template:

template <typename T>
T *myNew() {
    T *t = new T();
    t->push_to_list();
    return t;
}

Then call it like so:

MyClass *c = myNew<MyClass>();

OTHER TIPS

I don't understand why you are bothering with weak pointers.

I think your problem is not the specific question you're asking, but your design. Essentially, you are using globals, and that's usually a Bad Idea. Really, you should probably have some sort of World object, and among the things a World has is a collection of all actors in the world, a list of all bodies, and so forth.

So, your typical construction is, e.g., to create a new Combatant and stuff it into the world. Or maybe your world has a spawnCombatant.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top