I am sure most of my classes like for rendering text, sprite, shapes are not going to need more than one instance. Is it adequate to consider only this fact that its only going to need one instance? Should i also consider other things?
Do you think you don't need more than one or do you think there must never be more than one?
The singleton pattern is mostly useful in situations where the existence of more than one instance of a certain class isn't just unnecessary but would actually cause bugs, so you want to avoid at all cost that there ever is a second instance of it.
Also consider the alternative to a singleton: A purely
static class, which in C++ can alternatively be implemented as a
namespace. This is usually far easier to use and write and results in far more readable code. The main drawback is that you can't have a pointer or reference to a namespace. But I could hardly think of a situation where you would want that and where a singleton would still make sense.
The book Game Programming Patterns (which you can read free online) has a good overview of considerations for when to use / avoid singletons.
The cautionary advice boils down to:
A singleton is a global variable, with all the trouble that comes with it: (this also applies to static classes)
- Increasing the complexity of reasoning about your code, because now any two pieces of code that touch this singleton can indirectly affect each other, no matter how disparately they're separated in your code base.
- Encouraging coupling between two systems. You probably want the SpriteRenderer.RenderSprite() method called only by your main render loop. But by putting it in a singleton, it's accessible anywhere, making it easy for a junior programmer to shortcut the intended flow of rendering and, say, try to render an impact sprite in a collision handler - now your physics and rendering are coupled, even if you had a neat messaging system that could have avoided the coupling. (We have a habit of reaching for whatever tool seems most direct, and singletons are very direct!)
- Opening up to concurrency problems. Many modern games are multi-threaded, and a singleton is accessible to every thread, without knowledge of what the other threads are doing with it. This makes it easy to introduce bugs, or increase your code complexity with additional locks and checks.
Singletons solve multiple problems (convenient access, enforced uniqueness, lazy instantiation), when maybe we only needed to solve one. The extra features we didn't need can trip us up later.
- A common problem is to implement a singleton for convenient access early in a project when you only need one, so the uniqueness isn't a problem or a feature, just an inoffensive side-effect. If later you have a use case for multiple (eg. going from a single instance of Player to a multiplayer mode) then you have a lot of refactoring on your hands. (This is in line with Philipp & UnholySheep's advice: are you sure you never want more than one?)
- Lazy instantiation means the heavy work of constructing an instance could happen at an inopportune time in your game (eg. if you spin up your stat reporting service the first time the player picks up a collectible, it could cause a hitch in gameplay). If you know you'll need exactly one of these at all times, it might as well be a static class (or namespace as Philipp points out) so you skip any added complexity of a singleton, and your code is explicit about what's happening.
Check the article for some alternatives that may get the functionality you need without the singleton baggage. Singletons aren't necessarily bad, but the case you describe doesn't sound like one that needs a singleton solution.