but I need to change too much stuff to switch to composition, is it likely that using inheritance will cause me problems later on? :huh:
What you're saying here is "I don't like the structure, but I don't want to fix it, so instead I add more ugliness". Some call it "technical debt" which is an interesting viewpoint to read about some time.
So let me ask you, when would be the time to fix it, if it is not now? What must happen for you to decide you cannot continue and need to fix it first? (I don't need the answer, but ponder about it.)
Stacking more stuff on top of it does not make the underlying mess go away. You'll bump into it each time you make another extension or modification. What's worse, the more stuff you stack onto it, the more stuff you're going to have to rewrite when you eventually decide to fix the underlying structure. Each line of code that you write that uses a bad foundation will be thrown away, and will have to be written again when you change the foundation.
You're digging yourself deeper and deeper into the current situation with each addition.
It may look as counter-effective to rewrite what you have now, and for some time it is (ie rewriting existing code doesn't give new features). On the other hand, you have learned now that your current solution has some less nice properties. Those properties will be a continuous and growing nuisance until you fix it by rewriting the structure. The question you have to answer yourself is, can you live with the nuisances, knowing that they will get worse as you bolt more things onto it, knowing that fixing it later will be even more work than now ?
Deciding when to rewrite some code is part of learning to program. To make such a judgment, I think it would be good if you experience yourself both sides of that decision. That would put you in the situation where you can make an informed decision. Pick a decision, and live with the consequences.
Personally, I prefer a clean and proper design much more than getting the job done. I have been programming about 35 years, and I still usually start at the wrong end of the problem, needing a rewrite 2 or 3 times before all the puzzle-pieces fit. I don't think it's a waste of time. Each rewrite gives me a better structure that is more pleasant to work in, and maintain (I have a lot of code at work that is continuously modified with new experiments or ideas that need to be tested.) Rewriting also gives me new and deeper insights in the nature of the problem, making my design fit better to the problem being solved (even after all this time, I still find it amazing that picking the right ideas for the design solves at least half the problem). Last but not least, if, in the last attempt performance problems surfaced, a rewrite gives the opportunity to invent a better design that shifts the performance problems to a less problematic area.
that there is an 'Update Method' design pattern, that solves my problem. ( if someone is interested: http://gameprogrammingpatterns.com/update-method.html )
I quoted an earlier sentence, but it fits better with my reply to your questions, so bear with me.
I am very much against new programmers using design patterns as guide.
You'll probably need a little explanation on that view.
Around 25 years ago, computer science invented object oriented programming. People loved it, and in around 20 or so years, everybody is using it. Then some smart guys found that the same kind of structures could be found to solve certain common problems all over the place. They started to collect them, and organize them. They wrote the famous "gang of four" book "Design patterns" and lots of people were very happy with it. This is fine, programmers got names for commonly used ways of solving certain sub-problems, which helps a lot in discussing alternative approaches to solve whatever they're solving (saying "maybe the visitor pattern would work" communicates a whole set of class and object structure to everybody, in 6 words).
Do note however, we're talking about a small subset of solutions for a small subset of problems. Those problems occur a lot, but it's a subset of all problems that need to be solved.
Then someone said "Now wait a minute, if these design patterns happen all over the place, couldn't we design a solution from those patterns?". For experienced programmers, this makes sense imho. You use working common solutions for a large part of the design, so you can spend more time on the remaining more tricky areas with custom solutions. It's sound engineering.
For new programmers however, the situation is different. They don't know what's possible with "custom solutions". They don't know why the common solution is the common solution. They don't know when to stop following a design pattern, and make something better instead. I believe that giving a new programmer a standard set of building blocks saying "this is the universe of solutions, have fun building the world" is a very bad move. It has the big danger of locking a new programmer into the mindset that all problems can be solved by these design patterns, which is simply not true. The set of solutions is much much bigger, there are whole areas where a carefully constructed data structure will make the difference between day and night. A new programmer wil never ever encounter them if he/she sticks with using a design pattern for everything.
I think a new programmer should freely explore the entire world, finding what works for him/her. Inventing weird data structures, and trying how they work, and what their problems are. That's where the novel ideas are, the excellent solutions that we don't know about yet.
Once they understand the entire solution space, they can look at design patterns, and judge their value within the universe of all possible solutions.
I really like the 3rd solution where I just put an empty update method to a inactive object. It's better than making two vectors and transferring objects between them when created/destroyed/went-to-inactive-from-active.
I don't quite agree with your reason (you can simply hide such details in an object), but the conclusion seems fine to me. That decision is one step towards a "God" object though, where one object has all knowledge, and can do everything. For this reason I am not much of a fan for high level abstract "Game object" like classes, as they push towards all-knowing hierarchies, but it's a trade-off. You always have pain somewhere, the question is, where is the point where it hurts least.
I will waste too much time looping through the vector, because I would have to check if some flag == true for every object. This sounds really funny to me, worrying about a tiny 'for' loop, but he seems like a professional.
Hmm, I am a professional too, should I now agree with him? :)
Many of todays professionals were raised at a time where CPU time was very precious. It made a real difference if you could skip a whole set of tests that you'd know to be false. Obviously, this is still sound logic. Not doing something is always faster than trying it and then deciding each time, there is nothing you have to do. The difference however is that with modern processors, "precious" has shifted from the processor core only (running the test instructions) to the CPU memory caches (L1, L2, and perhaps L3) first, and the processor core second. This makes drawing conclusions on performance at the drawing board a hazardous area to say the least. I have seen one case in real code where testing an always-true value was actually faster than removing the test!
So yes, I agree with you, it's not something you should worry about. In fact, I would take it a few steps further even.
You seem to be constantly looking for "the best solution for X". In general, that doesn't exist at the point where you are now. Any "best" solution exists only, after you wrote the entire program, and you have analyzed all other possible options (there exist infinitely many, so that could take a while), and you have proven they are all worse than this one best solution.
In other words, it is highly unlikely that you actually have the best solution for anything. You don't even have the complete program yet, so you cannot even truthfully compare it with a second solution in the context of the finished program. As you may now realize, nobody knows what "best" is, and it takes too much time to figure it out. It exists, but we don't have any clue how to find it within our finite life time.
Luckily, this is not a major problem. There is a very large set of "acceptable" solutions, they are less good than "the best", but not that much worse (with varying degrees of worse). In fact, the common solution to this problem is "take something that is 'good enough' " [1] . So instead of asking "is this the best", ask yourself "do I know of any reason why it would not work good enough?". If the answer is "no", just use it. You'll make a mistake a couple of times, but that happens even more often if you look for "the best", since that is practically unobtainable, and in my opinion a not very interesting aim. Cpu cycles are cheap and life is short. Stop worrying about optimal solutions, code nicely working programs, and fix them when they appear broken in some way. This does mean you'll have to decide between ditching your current program and make a new better one from scratch, or live with the broken program, every now and then, but overall, I think it's a fair price to pay for making many nice programs that function in the way you envisioned.
[1]: I skipped the entire discussion of how we know what "good enough" is there. Sorry for that, but the post is long enough already, maybe another time.