Original answer
While your question is not very well defined, and it's not clear what you mean by "a lot" (instructions written in code, instructions invoked during a run, execution time actually spent casting), I'll give it a shot...
Yes, if you find yourself doing a lot of static casting there's likely a problem with your approach to the problem.
However, it seems that you're seeing "static casting" where there is none. Specifically, if you have a vector of (pointers to) GameObject
s you don't need to cast from their actual type to GameObject
- you're acting on them as GameObject
s even though in fact they are something else, and that's perfectly fine (since they are GameObject
s as well). Inserting Player
s or Weapon
s into your vector also doesn't involve any casting. If for some reason you're writing a lot of static_cast<GameObject&>(my_player)
or similar statements - either that's unnecessary or you've sort of put yourself into some software design hole.
Answer after OP's edit
So, you have a std::vector<GameObject>
s... well, like @Slava says, this won't work. Your static casts - that you probably use to insert things into your vector - are a bug - they 'slice' everything that's not part of GameObject
as it's inserted.
What you might want to do instead is:
- Use a
std::vector<GameObject *>
and act on your objects via pointers or references as I suggested above. This means that you allocate space for your GameObject
somewhere at which you know what subclass it is, without slicing. You will have to take care of freeing that memory, though.
- Use a or
std::vector<std::unique_ptr<GameObject>>
; again, you'll be accessing by a pointer - but it will be a "smart" one, which wraps a real pointer and takes care of deallocation. I suggested a std::unique_ptr
above but there's also std::shared_ptr
. This automation has costs, though, in the amount of space used during the game and the amount of time spent deallocating individual objects' memory.
- Use an
std::variant<Player, Enemy, Weapon>
. That might be a bit clunky, but you'll have the storage for your GameObject
within the vector, which is sometimes a plus. You'll access the relevant subclass instance with std::get<Player>(vector_of_objects[i])
. See the description of std::variant
for details.
Note these are not the only solutions, just a few alternatives based on your 20 characters of code...