Should you put executable code in linked list nodes?

Started by
18 comments, last by Stroppy Katamari 11 years, 4 months ago
Say I have an enemy class that I have multiples of, and I want to repeat actions with them by cycling through them in a (circularly?) linked list.
Is it acceptable to make them nodes in a linked list, executable code and all?
I asked one of my friends about it, and he told me to look up function pointers.

Could someone explain this to me in detail?
Advertisement
Your explanation of the situation is confusing. Do you mean you are storing the enemies in a list, or that you want to store "actions" in a list? What kind of "actions" are we talking about? When are they supposed to be ran? Do they affect all enemies, or just some?

In any case, I'm pretty sure this is not a problem you need function pointers for.
I mean, can I organize my enemy class in a linked lists where each enemy object is a node that has data, as well as actions that they can execute. I looked it up, but all the literature I found doesn't say anything about nodes using functions, only storing data.

I mean, can I organize my enemy class in a linked lists where each enemy object is a node that has data, as well as actions that they can execute. I looked it up, but all the literature I found doesn't say anything about nodes using functions, only storing data.

Sounds like you're thinking of making an Enemy class that both acts as its own linked-list node and as an enemy character. Based on The Single Responsibility Principle I would advise against that.

Instead, think of it this way: An enemy object *is* the data in a linked-list node.
In C++ this is actually really easy to do since there is already a linked-list container:

std::list<Enemy> linkedListOfEnemies;
So I just have to make a linked list of enemies?
I just didn't really know if the object was considered data or not. So it's perfectly fine right?

And how would I implement it without the standard container, from scratch?
Nevermind, I understand now. The data the node holds should be an enemy object, right.

Nevermind, I understand now. The data the node holds should be an enemy object, right.

Exactly.
And yes, in an OO language (like C++) an "object" is valid data to be in a variable or list ... and the fact that you can call that data object's methods is totally normal.
Why not just keep your enemies in a vector, and keep track of an the current enemy in the vector?


std::vector<Enemy> enemies;
unsigned currentEnemy = 0;

enemies[currentEnemy].DoSomething();
currentEnemy++;
if(currentEnemy >= enemies.size()) currentEnemy = 0;


You certainly could have enemies in a linked list, but what are you hoping to get out of that?

What are you wanting to do, that std::vector can't do for you? Dynamic arrays (like std::vector) have their pros and cons, and linked lists have their pros and cons. It most situations, though, the cons of std::vector are so minor that unless you are trying to hyper-optimize something, or are dealing with a staggering amount of data, it really doesn't make sense to not use it.
Well, would there be a particular drawback to having enemies in a linked list versus a vector?
Well, std::list<> is a standardized linked list, so if you used that, then the drawbacks would be very few. If you are making your own, there are more. Which is fine if making a linked list for personal education and practice, and not for real project code.

One drawback is element access speed - random access to an array is very very fast. Random access to a linked list is very very slow.

The benefits of linked lists are:
A) Fast inserting/removing in the front, back, or the middle.

The cons are:
B) Slow random-access.

The benefits of a vector are:
A) Fast inserting/removing from the back, with an occasional reallocation cost.
B) Fast random access.

The cons of a vector are:
A) Slow inserting/removing to the front or middle.

Each are equally good at "iterating in a loop" - in theory; though in reality I wouldn't be surprised if a vector outpaced the list.

However, if the real Pro vs Con is, "optimized for resizing, moving, removing" verses "optimized for accessing", then you have to ask yourself, how frequently do you insert/remove verses how frequently do you access or iterate?

If you add and destroy 200 enemies a frame, then a list might be preferable (though I'd still use a vector, personally, and just flag 'dead' enemies for reuse).
But more than likely, you add/destroy an enemy occasionally, but iterate over multiple enemies every frame.

It's really not a big deal whichever you go with, and overthinking it would be premature optimization... but the "proper" choice, if I'm understanding what you are wanting, is a vector - and it's good to know when to use what tool, and why it's better or worse in what situations.

Again, if your only reason for using a linked list is for circular iteration, then here is a circularly iterating vector:
myVector[index %= myVector.size()].DoSomething();

This topic is closed to new replies.

Advertisement