Thanks for watching, hope you enjoyed the video! Don't forget to check out hostinger.com/cherno and use code "cherno" to get up to 91% OFF yearly web hosting plans! ❤
That's a really good topic. I have messed with PHP and have seen patterns like MVC, event driven, modular.. And I'd like to know how it is in C++ world
There is one important functional difference between a namespace and a singleton class. In a namespace, all of the data is initialized/loaded into memory when the program first starts; this might be undesirable sometimes when we don't want all the data initialized until we actually need it. In contrast, singleton instances are only loaded during the first call to the "Get()" method.
Great content from an experienced developer. I would note that technically there's a little functional difference between static member variables and local static variables. When you moved the static inside the Get() function, you made the initialization order deterministic. Local static variables are initialized the first time control passes through the declaration. This makes it safe to call one singleton from another singleton. Also local static variables are thread-safe beginning with C++11 (except when --fno-threadsafe-statics is used in GCC). Plain old static member variables aren't thread safe, and the undefined initialization order causes a nightmare situation. This is less of an issue with ints and floats, but if a singleton contains a class, like a string, you're in a really big trouble. Especially when you're using one singleton/static from the constructor of another singleton/static, and you have no way of knowing which one gets initialized first, and if you're out of luck. You may be using a variable that hasn't even been constructed or assigned yet. The destruction order is an even bigger mess than the initialization order, so stay away from custom destructors that rely on other statics. The object being destructed may be using an object that has already been destructed earlier.
Actually, the standard guarantees that destruction order will always be the reverse of the construction order, so that's not so horrible. Thank you for your comment - it's what I would have written if you hadn't already posted.
Thanks for your comment, I had not used the first time of Singleton he showed , where he uses Static Member Variables, only with Local Static Variables. Now I know the differences. :D
If the statics are for making the variables have file-scope then it can save you some recompilation time when adding or removing data that is no longer part of the interface.
@Ralph Reilly If you add static before a global variable defined in a cpp it goes from being a global to having file scope. As in you can't access it outside the cpp. Means the compiler can rip out the symbol right away instead of waiting for the linker to do it. Moving the private statics in the class definition to the cpp would mean changing them wouldn't change the header at all so would avoid recompilation from header-changes.
One use case for C++ singleton that makes sense to me is the case where you have several classes with a common base class. Each of the derived classes could be a singleton, benefiting from reused code and encapsulation and they're similar enough to where it makes sense to derive them all from a single base virtual class. In this case, the base class takes care of most of the structure - making it reusable. Then the singleton derived classes have just a few minor differences for each of their use cases.
Great Video. First ran across singletons on a Java project (where, as you point out, everything is a class). Since then, used it occasionally if needed to reuse some object that was 'expensive' to create. One was where a lengthy connection to another server database had to be established. Each query on the object was stand-alone, but creation took time. So we created once in a singleton and then all the code could 'get' and 'query' without having to recreate the connection all the time.
A Log Class is a good example of a singleton. You just need a way to log things so you instantiate the Log singleton and can do Log.warning("something"). Other examples are in plugin architectures where a singleton can act as an API interface. You want to provide a certain class of functionality, then there is a singleton for that and you bind to it by registering handlers etc.
This is HUGE in embedded programming because we have to often interface with C libraries. The singleton pattern allows us to interface with C callbacks but still use dependency injection for unit test. I love your videos. You are doing this right. C++ is the best language ever made and you are making this accessible
Me and my friend had to give a 40 minute presentation about the Design Pattern, specifically using C++ as well. Singletons are, from what we've seen most of the time disliked and sometimes treated as an anti-pattern even. Now, Singletons do have their limited uses, so there's that. But how to construct one and especially how to destruct one or worse, doing that AND being in concurrent environment, that is a real piece of work. What Cherno did in construction was a Meyers Singleton, i.e. the local static one. There's also the way of allocating the singleton on a heap and checking if the pointer is null and if so, creating the Singleton, otherwise just returning the pointer as a reference. Threading usually involves something like double checked locking (you don't want to construct two singletons, that'd defeat their purpose) or something that ensures a single call of the constructor. Destruction is pretty funny too - you can either ignore possible problems or think of the Keyboard-Display-Logger problem and think of the Phoenix Singleton (where you basically remake the Singleton anew) or the Longevity Singleton, which requires a lot more work. If someone has a need to know more about Singletons, I recommend Modern Design Patterns in C++ or the original Design Patterns by GoF. Tbh, once we did that presentation, I started to see Singletons a lot more. E.g. my browser uses files to lock the processes and guess what, that's a Singleton. Never seen it before the presentation.
I've seen a lot of hate towards Singletons, and never really understood why. I'm a self taught C++ programmer and I use C++ to automate my work as an engineer, which involves a lot of data processing, e.g. sucking in a lot of data files and extracting data etc. So for example, for each kind of data file I have to read I will create a class to handle doing it, and rather than everything that Cherno just described I create a class, sometimes the Constructor is empty and sometimes data needs to be passed. But it's a lot easier than everything described in this video. And I don't see any way around it for the work I do.
@@axelBr1 Singletons are hated by pure OOP devs who suck off big bob and his clean code principles. While anyone outside of the OOP cult know that clean code is in itself an anti pattern that creates extreme bloat and complexity with its constant abstraction and FactoryFactoryFactories. Singletons remove all that bloat and complexity so the SOLID fanboys hate it.
@@abuDA-bt6ei Thanks! I've also being doing away with all the getters in my code and just making the variable public. If you want to F about with a variable then that's your problem. But filling the .hpp file with lots of .get... I don't think helps
We use a lot of static function variables in methods especially for fixes that should not break ABI (Introducing variables or reordering may break ABI). The best advantage from this approach is the guarantee for MT safety when initialization the variable - either better if the variable is a class. Something you didn't mention (Or I missed it) is MT thread safety which is the crucial point for singleton initialization. (Refers to the famous double-if-lock pattern).
Although useful for begginers Singletons are an anti-pattern and end up coupling your code and make it difficult to test. Try creating an IoC (inversion of control), which is basically an object you inject into a constructor that has single references to you global objects. A framework that uses reflection to do this is super useful.
You forgot to mention the most important thing. It's a antipattern and should not be used except few rare exceptions. It adds hidden dependencies into the whole codebase, makes unit testing harder and causes lots of pain and costs few years later.
sometimes it can make unit testing easier, because you can make your singleton inherit an interface and then use a mock instance for testing other stuff rather than the real singleton, actually anytime you want an essentially static module but you need it to inherit something then you basically need to make a singleton, i think thats the only time i can think of where it would be useful.
I used them in ue4 as a game audio programmer and found them to be tricky to work with. The engine instantiates the Singleton as expected but tweaks to the Singleton data doesn't show until the entire engine is rerun. That makes iterating on designs a lengthy trial. Otherwise it's a handy way to get your world actors to survive between map transitions.
Thanks cherno for all these videos. I binge watched you whole series almost a week ago so that I can be comfortable with c++ again(even more now). It really helped me to understand c++ codebase of mlpack organization, I even made a PR on it which is almost accepted. Thanks a lot.
1. create a private object inside a class..(mark it as static -> meaning that object is specific to an object //not shared with other objects) 2. mark constructor as private 3. make a public function to access that private object(return type is pass by reference because to refer an object that already being created not making a copy of it)
in short: - declare a class with a public Get()-function, a private constructor and define the static singleton instance somewhere - exec functions with Singleton::Get().function() OR alias Singleton first with Singleton& instance = Singleton::Get() and then use alias to call functions: instance.function() - don't forget to delete the copy constructor: Singleton(const Singleton&) = delete; you can also put the instantiating part into the Get() function of the class, as static variables will not be instantiated twice.
Dare I say, your playlist of C++ videos are the best in the universe so far, youtube aside. I can not thank you enough. If I had the financial ability, Id definitely join the patreon group, not for the extra access but just to show my support for the greatest C++ videos on the net. Who knows, maybe I will get there soon.
I love your video. Some explanations (e.g. the linkedin explanation ) are confusing because they use complicated classes as their demo. I really liked how you didn't bother making a working random generator function and focused on singletons!
I make the pointer static and initialize that to NULL. The get_instance method checks the static pointer for NULL and will instantiate it if NULL, so one instance.
Singleton as class allows "optional singletons", so I can have singleton, but i can benefit to able create a new standalone instance for some special purpose. Singletons as class can also extend some interface. Putting instance to static variable outside of function Get is slightly faster, then having it inside of the function Get because every-time the Get() it called, it must ask, whether the instance is already initialized. There is also some locking protocol to ensure MT safety. This doesn't applied to outside variable. However there is also benefit to having the static variable inside of the function. If the singleton is never used, it is also never initialized, which can help with performance in the such case.
this is called Meyer's singleton and after c++11 it is thread safe too, but has an overhead cost of the Get functuion because of the internal locking mechanism
@@rblackmore1445 yeah but it is not obvious that there is a locking in this code and it was not before c++11, it was added to the standard later, as Meyers states: - Static function objects are initialized when control flow hits the function for the first time. - The lifetime of function static variables begins the first time the program flow encounters the declaration and ends at program termination. - If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
@@rblackmore1445 With the right memory model (which C++ didn't have as part of the language spec pre-C++11 though may now, I'm not sure), you can construct a safe "double checked" locking scheme that really doesn't suffer much.
In general singletons have some overhead for the function calls and initialization when you need to access. In addition, it's hard to reason about initialization and shutdown order so I completely avoid them in my engine. Instead I have a class that contains static instances of all the engine components. I can explicitly control startup and shutdown this way. It's not perfect though as c++ guarantees initialization before access in multithreaded environments, however, I've found that even with this performance cost, it's about 50% faster than using singletons
Loving the content! Could you possibly do a video on iterators? As far as what they are, how you can use them in a queue/linked list implementation, etc
I use Singletons at work, and I learned something. Deleting the copy constructor. When I researched this topic I had not seen this part before. You did not touch on the part of deleting the actual singleton, Im not sure if its actually an important thing to look into when using Singletons, but I have heard there is a particular way to actually delete the singleton in order to evade memory leaks?,
If you do this, or use directly accessed namespaced data, you can run into something called the static initialization order fiasco. All global and class level static data gets initialized before the main function ever executes. Because there are no rules in the C++ standard dictating in what order translation units will be initialized you could end up with code depending on data that has not been initialized yet, causing a crash. Exceptions are also tricky to handle with "static classes", because you can't write exception handlers for code that runs before your main ever gets called. If a static object does throw on construction you end up with implementation defined behavior. That being said, you can use this pattern as long as you are entirely sure you aren't depending on any static variables outside your own translation unit and aware of the initialization order within your own translation unit. A singleton doesn't have this problem because the data is lazily initialized whenever you first need it.
@@ilendur3810 This is correct and I wish the video mentioned this, for me the video didn't really show why singletons would be useful. There are also some libraries that will not let you use certain functions during static initialization. But it's important to point out that this all only applies to the pattern when lazy initialization is used, in other words the style where you put the static variable inside the function, if you just have it as a private static class variable there can still be problems.
I think a big advantage of singletons is that you can put init code in the constructor and not worry about calling it manually. Advantage or disadvantage, depending on if the init code relies on some other singleton that may or may not have been initialized
OMG, You're even married, Lol, Its been 7 years man, since I followed your channel and waited for you to release more videos, TH-cam recommendations have brought us back together lol.
I recently used a singleton for a SDL wrapper. I wrote an initializer class in the protected field of the window class with a static instance of that initializer such that once the user instantiate a window, it will initialize SDL automatically in the constructor of the static initializer object and de-initialize it at the end of the main in the destructor of the initializer. I've not yet used singletons in other ways than the one I described and I simply don't use them that much.
Good video! Only thing I missed is the downsides of the singleton pattern. For example, they are pretty much untestable in unit tests. And then there is threading issues. Also, the initialization order fiasco. In my opinion, this pattern has so many issues and too few benefits to balance it out.
@@adamjcasey how do you test a function that make use of your singleton in an environment where your singleton is not present? say you have that classical database singleton. while unit testing, you most likely want to swap your database connection with some sort of mock, which would be pretty easy with dependency injection, but is impossible with a singleton. a singleton is global state. global state is evil. it is untestable in unit tests.
Note: function local static variables (depending on implementation) can have guards for thread safety, which make accesses take longer. This can be particularly problematic when it's a pointer because of the dependency stall.
A question ! Is there any advantage of Singletons over pure static class ? (With static methods and attributes, and private constructor) i.e: class Random{ public: static float Float(){return m_number;}; private: Random(){}; static float m_number; }; float Random::m_number = 0.5; int main(){ std::cout
What I missed in your video is the ability to control when the singleton instance is deleted again. This can be important, for example, when analyzing memory leaks. Without explicit control, the singleton instance is only deleted "too late", so that it is always detected as memory leak (provided that the singleton instance allocates dynamic memory, which of course is rather irrelevant for the random number generator from your example).
I use singletons just if you must be able to reinit the object, for example restarting a server etc. Then you can just reassign the object and don't have to worry about those variables
I just made a tic tac toe c++ game and my main downside was that I had to call “TicTacToe main;” at the beginning of the file. I went on TH-cam and this is the first thing I saw! Thanks man!
Already knew about singletons, but super helpful that I learned how to circumvent the cumbersome declaration of the static instance in the translation unit.
So singletons are basically the overcomplicated version of namespaces with public and private sections (yes, I know there is no pub, and priv sections for namspaces)...
12:15 Why don't we just mark m_RandomGenerator as static? Isn't static float m_RandomGenerator equal to float m_RandomGenerator when there is no instance anyway, thus we can call it in static member function, isn't it?
8:05 Get is just about one of the most none- telling method names in popular use out there, ever! Firstly, if you call a method or function - especially one without arguments - it is nearly obvious that you are already trying to query for something when the use pattern is such that the return value is acted upon. Stating the obvious part (get, query) adds nothing of value to the code. It is much better to say what is actually being returned/ acted upon/ or "got" from somewhere, as that is usually the essential thing to know. The "get" part (as the complementary "set" name) is nothing but noise, especially in long chains like bar.set(my.foo.get().getThis().getThat().getValue().get().asInteger()); The real action is lost in that endless recitation of get get get. Personally I think this habit should be considered an anti-pattern in itself. In the GoF description of the Singleton pattern the static method in question is called simply Instance() IIRC, and that does at least communicate something relevant. (Also, contrary to popular beliefs in the OOP community the word "set" is not the opposite of "get".)
Two days ago I (C++ n00b) was asking a friend (former games developer) about static variables outside of a class for a physics simulation code and he said it's a hacky way of storing global variables. He said it's probably better to create a class to store all the simulation variables and I had no idea why he'd say that. I guess now I know.
In other languages I would stuff my game state into a singleton. And then I tried it in c++ and wow, mistakes were made. I can't even describe to you how deep the cyclic dependency error crap went...
Greetings, Cherno. I think the singleton pattern is very very important. In your video material you showed the case of singleton object being copied. I think, that was a great misuse of singleton paradigm, because it must not be ever copied but only got by reference or pointer. Could the "explicit" runeword make your example more prone of errors? Or any other ways?
Man, I honestly don't see why I would use this. I mean, when you understand it, it becomes clear, but the fact is that you _have_ to understand a thing that could really be simpler and shorter. Am I missing something? Do singletons have any advantages compared to namespaces in C++?
Tachi Singleton classes can still have constructors and destructors, while namespaces would require you to write and call initialization and shutdown functions. An easy way to demonstrate the advantage of a singleton over a namespace would be a class that logs text to a file, where the constructor and destructor could be used the open and close a handle to the file.
@@Tachi107 That's good, as I think Singleton is vastly overused. It really only makes sense for things that are universally cross cutting, should only have one shared instance, and a plain old global isn't good enough. Think loggers (and even then, I don't think Singleton is worthwhile).
It's just where static variables are stored. I guess that everything that is in static memory is destroyed at the end of the program, instead of being destroyed at the end of their scope, and that's it.
Great vid, One of my use cases for Singlton in real life is database connection, for every request you get, it's better to establish 1 connection to the database, and use it throughout the code, instead of re-establishing connection for every query which will slow down your app.
What's the advantage of being able to create your own variable with a reference to the singleton instance? Why would you ever want to write Singleton& instance = Singleton::Get(); ? My thought was.. why not put the Get() method in the private sector all together, when all of your reachable method are marked as static anyways? If you want to access the (same..?) instance again, you will do so by calling ::Get() or just by using the static functions anyway
Thank you so much! Your videos are so good. Thanks to you I learned some little details that are important to know about C++. I would love to see more on idioms. The only idiom everyone seems to use for tutorials is the pimpl idiom.
Thank you The cherno. This is great, just what I need. I wish you can look at more design patterns in future, I mean yuo realyy explain in a way that makes it easy to understand.
I think speaking of Singletons without mentioning dependency injection is somewhat pointless, as you actually covered that without the implementation being derived from somewhere above, the singleton class can be simply replaced by a namespace and have the same functionality. Since I'm far not a c++ expert, I actually wonder in what ways can a dependency injection implemented in c++. I can imagine ways of doing that, but I don't really think those are good ways, so perhaps covering that part may be good.
I really like your explanation very much, the way you construct the solution makes things more easy, Please add video on all the other class Design Patterns
Really good! but you are depending on default constructor. what if your class constructor needs some parameters? then how can your get function do it? what I see is the class static instance should be a pointer and not just an object. with pointer you can invoke the required constructor. consider: #include using namespace std; #include class Point { public: static std::unique_ptr& getInstance() { return instance; } static void createInstance(int x, int y) { if (!instance) instance = std::make_unique(Point(x, y)); } static void releaseInstance() { instance.reset(); } int getX() const { return this-> x; } int getY() const { return this-> y; } void setX(int x) { this->x = x; } void setY(int y) { this->y = y; } private: static std::unique_ptr instance; // no need to delete copy constructor and copy assignment; this causes them deleted automatically. (if a class has a member whose copy control operations are deleted then this class's also are deleted) int x; int y; Point(int = 0, int = 0); }; //Initialize pointer to zero so that it can be initialized in first call to createInstance std::unique_ptr Point::instance = 0; Point::Point(int a, int b) : x(a), y(b) {} int main() { Point::createInstance(10, 20); std::unique_ptr& pt = pt->getInstance(); cout
I'm new to c++ but am hoping to use it a bit like c so that not everything is object oriented. Instead of a singleton, could it work as well to simply use global functions inside a namespace? Assuming there is no state that the class is required to have.
I am writing an RNG that generates the numbers on the GPU in the background for my diploma thesis. I considered doing it like this when I first started but I realized that one should be able to initialize multiple instances of RNG in a multithreaded program - one for each thread. I could use a single instance and a mutex, yes, but that would have a huge performance hit, which is the opposite of what I want.
Does marking the copy constructer as delete have to be performed under public:? or could it be done under private: ? would there be consequence of this?
why don't you use the constructor in the get method? won't simply returning the variable without putting a reference in it cause SegFault? Is it because, being static it gets initialised with a valid instance?
Thanks for watching, hope you enjoyed the video! Don't forget to check out hostinger.com/cherno and use code "cherno" to get up to 91% OFF yearly web hosting plans! ❤
The Cherno make a data structure series bro
lmao "up to 91% off"... My price went from $138 to $129...
Can i have an English subtitle to help with my study?
@The Cherno, can you explain *Dependancy Injection* pattern in C++ ?
Please make a most used design pattern related series... much needed..
I'd really like more of such design pattern content. Big fan btw, great content.
That's a really good topic. I have messed with PHP and have seen patterns like MVC, event driven, modular.. And I'd like to know how it is in C++ world
There is one important functional difference between a namespace and a singleton class. In a namespace, all of the data is initialized/loaded into memory when the program first starts; this might be undesirable sometimes when we don't want all the data initialized until we actually need it. In contrast, singleton instances are only loaded during the first call to the "Get()" method.
Great content from an experienced developer. I would note that technically there's a little functional difference between static member variables and local static variables. When you moved the static inside the Get() function, you made the initialization order deterministic. Local static variables are initialized the first time control passes through the declaration. This makes it safe to call one singleton from another singleton. Also local static variables are thread-safe beginning with C++11 (except when --fno-threadsafe-statics is used in GCC). Plain old static member variables aren't thread safe, and the undefined initialization order causes a nightmare situation. This is less of an issue with ints and floats, but if a singleton contains a class, like a string, you're in a really big trouble. Especially when you're using one singleton/static from the constructor of another singleton/static, and you have no way of knowing which one gets initialized first, and if you're out of luck. You may be using a variable that hasn't even been constructed or assigned yet. The destruction order is an even bigger mess than the initialization order, so stay away from custom destructors that rely on other statics. The object being destructed may be using an object that has already been destructed earlier.
Tamas Demjen
We really need people like you in the comments section
Actually, the standard guarantees that destruction order will always be the reverse of the construction order, so that's not so horrible.
Thank you for your comment - it's what I would have written if you hadn't already posted.
Thanks for your comment, I had not used the first time of Singleton he showed , where he uses Static Member Variables, only with Local Static Variables. Now I know the differences. :D
If the statics are for making the variables have file-scope then it can save you some recompilation time when adding or removing data that is no longer part of the interface.
@Ralph Reilly If you add static before a global variable defined in a cpp it goes from being a global to having file scope. As in you can't access it outside the cpp. Means the compiler can rip out the symbol right away instead of waiting for the linker to do it. Moving the private statics in the class definition to the cpp would mean changing them wouldn't change the header at all so would avoid recompilation from header-changes.
One use case for C++ singleton that makes sense to me is the case where you have several classes with a common base class. Each of the derived classes could be a singleton, benefiting from reused code and encapsulation and they're similar enough to where it makes sense to derive them all from a single base virtual class. In this case, the base class takes care of most of the structure - making it reusable. Then the singleton derived classes have just a few minor differences for each of their use cases.
Great Video. First ran across singletons on a Java project (where, as you point out, everything is a class). Since then, used it occasionally if needed to reuse some object that was 'expensive' to create. One was where a lengthy connection to another server database had to be established. Each query on the object was stand-alone, but creation took time. So we created once in a singleton and then all the code could 'get' and 'query' without having to recreate the connection all the time.
A Log Class is a good example of a singleton. You just need a way to log things so you instantiate the Log singleton and can do Log.warning("something"). Other examples are in plugin architectures where a singleton can act as an API interface. You want to provide a certain class of functionality, then there is a singleton for that and you bind to it by registering handlers etc.
Yes! Please, do cover more Design Patterns!
Side question: can you type and talk like that or is that edited? Regards!
This is HUGE in embedded programming because we have to often interface with C libraries. The singleton pattern allows us to interface with C callbacks but still use dependency injection for unit test.
I love your videos. You are doing this right. C++ is the best language ever made and you are making this accessible
thanks for this comment!
Can you share link to any of your public repository?
Cherno, have you considered covering more design patterns in the C++ series? Thanks!
I am so damn happy this series is back. Have been waiting for a c++ video for so long!!
Keep it up, i am a student that is c++ geek. I learnt a lot through you.
more design patterns please!! you're by far the best C++ teacher on yt
Me and my friend had to give a 40 minute presentation about the Design Pattern, specifically using C++ as well.
Singletons are, from what we've seen most of the time disliked and sometimes treated as an anti-pattern even. Now, Singletons do have their limited uses, so there's that. But how to construct one and especially how to destruct one or worse, doing that AND being in concurrent environment, that is a real piece of work.
What Cherno did in construction was a Meyers Singleton, i.e. the local static one. There's also the way of allocating the singleton on a heap and checking if the pointer is null and if so, creating the Singleton, otherwise just returning the pointer as a reference.
Threading usually involves something like double checked locking (you don't want to construct two singletons, that'd defeat their purpose) or something that ensures a single call of the constructor.
Destruction is pretty funny too - you can either ignore possible problems or think of the Keyboard-Display-Logger problem and think of the Phoenix Singleton (where you basically remake the Singleton anew) or the Longevity Singleton, which requires a lot more work.
If someone has a need to know more about Singletons, I recommend Modern Design Patterns in C++ or the original Design Patterns by GoF.
Tbh, once we did that presentation, I started to see Singletons a lot more. E.g. my browser uses files to lock the processes and guess what, that's a Singleton. Never seen it before the presentation.
I've seen a lot of hate towards Singletons, and never really understood why. I'm a self taught C++ programmer and I use C++ to automate my work as an engineer, which involves a lot of data processing, e.g. sucking in a lot of data files and extracting data etc. So for example, for each kind of data file I have to read I will create a class to handle doing it, and rather than everything that Cherno just described I create a class, sometimes the Constructor is empty and sometimes data needs to be passed. But it's a lot easier than everything described in this video. And I don't see any way around it for the work I do.
@@axelBr1 Singletons are hated by pure OOP devs who suck off big bob and his clean code principles. While anyone outside of the OOP cult know that clean code is in itself an anti pattern that creates extreme bloat and complexity with its constant abstraction and FactoryFactoryFactories. Singletons remove all that bloat and complexity so the SOLID fanboys hate it.
@@abuDA-bt6ei Thanks!
I've also being doing away with all the getters in my code and just making the variable public. If you want to F about with a variable then that's your problem. But filling the .hpp file with lots of .get... I don't think helps
We use a lot of static function variables in methods especially for fixes that should not break ABI (Introducing variables or reordering may break ABI).
The best advantage from this approach is the guarantee for MT safety when initialization the variable - either better if the variable is a class.
Something you didn't mention (Or I missed it) is MT thread safety which is the crucial point for singleton initialization.
(Refers to the famous double-if-lock pattern).
Although useful for begginers Singletons are an anti-pattern and end up coupling your code and make it difficult to test. Try creating an IoC (inversion of control), which is basically an object you inject into a constructor that has single references to you global objects. A framework that uses reflection to do this is super useful.
this. global state is just bad.
You forgot to mention the most important thing.
It's a antipattern and should not be used except few rare exceptions.
It adds hidden dependencies into the whole codebase, makes unit testing harder and causes lots of pain and costs few years later.
sometimes it can make unit testing easier, because you can make your singleton inherit an interface and then use a mock instance for testing other stuff rather than the real singleton, actually anytime you want an essentially static module but you need it to inherit something then you basically need to make a singleton, i think thats the only time i can think of where it would be useful.
I used them in ue4 as a game audio programmer and found them to be tricky to work with. The engine instantiates the Singleton as expected but tweaks to the Singleton data doesn't show until the entire engine is rerun. That makes iterating on designs a lengthy trial. Otherwise it's a handy way to get your world actors to survive between map transitions.
Thanks cherno for all these videos. I binge watched you whole series almost a week ago so that I can be comfortable with c++ again(even more now). It really helped me to understand c++ codebase of mlpack organization, I even made a PR on it which is almost accepted. Thanks a lot.
1. create a private object inside a class..(mark it as static -> meaning that object is specific to an object //not shared with other objects)
2. mark constructor as private
3. make a public function to access that private object(return type is pass by reference because to refer an object that already being created not making a copy of it)
even though we declared constructor as private, there are still a default public copy constructor created by the compiler..so need to delete that too
@12:55 can be assigned to a another reference object/variable like so
auto& reference=Random::Get().Float();
in short:
- declare a class with a public Get()-function, a private constructor and define the static singleton instance somewhere
- exec functions with Singleton::Get().function() OR alias Singleton first with Singleton& instance = Singleton::Get() and then use alias to call functions: instance.function()
- don't forget to delete the copy constructor: Singleton(const Singleton&) = delete;
you can also put the instantiating part into the Get() function of the class, as static variables will not be instantiated twice.
YAY! More C++ :)
Dare I say, your playlist of C++ videos are the best in the universe so far, youtube aside. I can not thank you enough. If I had the financial ability, Id definitely join the patreon group, not for the extra access but just to show my support for the greatest C++ videos on the net. Who knows, maybe I will get there soon.
I love your video. Some explanations (e.g. the linkedin explanation ) are confusing because they use complicated classes as their demo. I really liked how you didn't bother making a working random generator function and focused on singletons!
I make the pointer static and initialize that to NULL. The get_instance method checks the static pointer for NULL and will instantiate it if NULL, so one instance.
Glad to hear you say you're just getting started! Can't wait!
Singleton as class allows "optional singletons", so I can have singleton, but i can benefit to able create a new standalone instance for some special purpose. Singletons as class can also extend some interface.
Putting instance to static variable outside of function Get is slightly faster, then having it inside of the function Get because every-time the Get() it called, it must ask, whether the instance is already initialized. There is also some locking protocol to ensure MT safety. This doesn't applied to outside variable. However there is also benefit to having the static variable inside of the function. If the singleton is never used, it is also never initialized, which can help with performance in the such case.
this is called Meyer's singleton and after c++11 it is thread safe too, but has an overhead cost of the Get functuion because of the internal locking mechanism
everything with locking has overhead
@@rblackmore1445 yeah but it is not obvious that there is a locking in this code and it was not before c++11, it was added to the standard later, as Meyers states:
- Static function objects are initialized when control flow hits the function for the first time.
- The lifetime of function static variables begins the first time the program flow encounters the declaration and ends at program termination.
- If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
@@rblackmore1445 With the right memory model (which C++ didn't have as part of the language spec pre-C++11 though may now, I'm not sure), you can construct a safe "double checked" locking scheme that really doesn't suffer much.
In general singletons have some overhead for the function calls and initialization when you need to access. In addition, it's hard to reason about initialization and shutdown order so I completely avoid them in my engine. Instead I have a class that contains static instances of all the engine components. I can explicitly control startup and shutdown this way. It's not perfect though as c++ guarantees initialization before access in multithreaded environments, however, I've found that even with this performance cost, it's about 50% faster than using singletons
What about an another singleton kind: class MyClass { ...members... } myClass; its a typedef or is same as singleton pattern in C++?
Loving the content! Could you possibly do a video on iterators? As far as what they are, how you can use them in a queue/linked list implementation, etc
I use Singletons at work, and I learned something. Deleting the copy constructor. When I researched this topic I had not seen this part before.
You did not touch on the part of deleting the actual singleton, Im not sure if its actually an important thing to look into when using Singletons, but I have heard there is a particular way to actually delete the singleton in order to evade memory leaks?,
17:25 cant you just have a class with everything static instead of a namespace so you can have private / public
If you do this, or use directly accessed namespaced data, you can run into something called the static initialization order fiasco. All global and class level static data gets initialized before the main function ever executes. Because there are no rules in the C++ standard dictating in what order translation units will be initialized you could end up with code depending on data that has not been initialized yet, causing a crash. Exceptions are also tricky to handle with "static classes", because you can't write exception handlers for code that runs before your main ever gets called. If a static object does throw on construction you end up with implementation defined behavior. That being said, you can use this pattern as long as you are entirely sure you aren't depending on any static variables outside your own translation unit and aware of the initialization order within your own translation unit. A singleton doesn't have this problem because the data is lazily initialized whenever you first need it.
I was thinking the same thing, and thank you @Ilendur for explaining
@@ilendur3810 This is correct and I wish the video mentioned this, for me the video didn't really show why singletons would be useful.
There are also some libraries that will not let you use certain functions during static initialization.
But it's important to point out that this all only applies to the pattern when lazy initialization is used, in other words the style where you put the static variable inside the function, if you just have it as a private static class variable there can still be problems.
@@ilendur3810 but you can just use a "Initialize" method to initialize later the class
I think a big advantage of singletons is that you can put init code in the constructor and not worry about calling it manually. Advantage or disadvantage, depending on if the init code relies on some other singleton that may or may not have been initialized
OMG, You're even married, Lol, Its been 7 years man, since I followed your channel and waited for you to release more videos, TH-cam recommendations have brought us back together lol.
@morph611 Lol
Hahaha lol
I've noticed that too his married that's for sure 😄
I recently used a singleton for a SDL wrapper. I wrote an initializer class in the protected field of the window class with a static instance of that initializer such that once the user instantiate a window, it will initialize SDL automatically in the constructor of the static initializer object and de-initialize it at the end of the main in the destructor of the initializer.
I've not yet used singletons in other ways than the one I described and I simply don't use them that much.
Thanks for your great videos, can you please make a tutorial about DESIGN PATTERNS
Good video! Only thing I missed is the downsides of the singleton pattern. For example, they are pretty much untestable in unit tests. And then there is threading issues. Also, the initialization order fiasco. In my opinion, this pattern has so many issues and too few benefits to balance it out.
Well designed singletons are very testable! What do you mean?
@@adamjcasey how do you test a function that make use of your singleton in an environment where your singleton is not present?
say you have that classical database singleton. while unit testing, you most likely want to swap your database connection with some sort of mock, which would be pretty easy with dependency injection, but is impossible with a singleton.
a singleton is global state. global state is evil. it is untestable in unit tests.
I'm bagging you: more design patterns!
great video!
Note: function local static variables (depending on implementation) can have guards for thread safety, which make accesses take longer. This can be particularly problematic when it's a pointer because of the dependency stall.
More c++ ep please!
A question ! Is there any advantage of Singletons over pure static class ? (With static methods and attributes, and private constructor)
i.e:
class Random{
public:
static float Float(){return m_number;};
private:
Random(){};
static float m_number;
};
float Random::m_number = 0.5;
int main(){
std::cout
This is kind of a late reply, but the thing is that you can't pass a static class as a parameter. Singletons let you treat them like any other object.
Static class is initialized before main() and you don't have any control over order of initialization I guess.
What I missed in your video is the ability to control when the singleton instance is deleted again. This can be important, for example, when analyzing memory leaks. Without explicit control, the singleton instance is only deleted "too late", so that it is always detected as memory leak (provided that the singleton instance allocates dynamic memory, which of course is rather irrelevant for the random number generator from your example).
I use singletons just if you must be able to reinit the object, for example restarting a server etc. Then you can just reassign the object and don't have to worry about those variables
I just made a tic tac toe c++ game and my main downside was that I had to call “TicTacToe main;” at the beginning of the file. I went on TH-cam and this is the first thing I saw! Thanks man!
I made it using Object oriented programming by the way, hence the reason why I had to declare the instance
I particularly would like to see a video on the Command pattern, since I've been told its useful for game dev.
I agree, of course there are other resources for that, but I really like the way Yan explains things!
FWIW, Singeltons are used quite a bit in embedded designs to control access to hardware.
Best C++ tutorials on the internet. Hostinger better be giving you some good money.
You C++ classes are simply brilliant. Thank you.
"Let's just pick on Java" xD sad Java noises
Eemeli Lehtonen same :)
17:57 why are you using static for the function and variable in the namespace?
So the value stays consistent across classes of that type.
@@samuelrasquinha6712 But in the namespace there is no class. IMO it is much simpler than a singleton with basically no downsides.
Already knew about singletons, but super helpful that I learned how to circumvent the cumbersome declaration of the static instance in the translation unit.
So singletons are basically the overcomplicated version of namespaces with public and private sections (yes, I know there is no pub, and priv sections for namspaces)...
12:15 Why don't we just mark m_RandomGenerator as static? Isn't static float m_RandomGenerator equal to float m_RandomGenerator when there is no instance anyway, thus we can call it in static member function, isn't it?
This was pretty useful and easy to understand. Thank you!
8:05 Get is just about one of the most none- telling method names in popular use out there, ever! Firstly, if you call a method or function - especially one without arguments - it is nearly obvious that you are already trying to query for something when the use pattern is such that the return value is acted upon. Stating the obvious part (get, query) adds nothing of value to the code. It is much better to say what is actually being returned/ acted upon/ or "got" from somewhere, as that is usually the essential thing to know. The "get" part (as the complementary "set" name) is nothing but noise, especially in long chains like bar.set(my.foo.get().getThis().getThat().getValue().get().asInteger()); The real action is lost in that endless recitation of get get get. Personally I think this habit should be considered an anti-pattern in itself. In the GoF description of the Singleton pattern the static method in question is called simply Instance() IIRC, and that does at least communicate something relevant. (Also, contrary to popular beliefs in the OOP community the word "set" is not the opposite of "get".)
Two days ago I (C++ n00b) was asking a friend (former games developer) about static variables outside of a class for a physics simulation code and he said it's a hacky way of storing global variables. He said it's probably better to create a class to store all the simulation variables and I had no idea why he'd say that. I guess now I know.
In other languages I would stuff my game state into a singleton.
And then I tried it in c++ and wow, mistakes were made. I can't even describe to you how deep the cyclic dependency error crap went...
The indirection is a great idea. I have never thought of it like this 👍
Greetings, Cherno.
I think the singleton pattern is very very important. In your video material you showed the case of singleton object being copied.
I think, that was a great misuse of singleton paradigm, because it must not be ever copied but only got by reference or pointer.
Could the "explicit" runeword make your example more prone of errors? Or any other ways?
Probably, the Singleton pattern shall be accompanied by Pimple idiom. But regular developers are too lazy.
Your fast typing is so satisfying
I use a singleton for my data provider where I have to keep track of every request sent within a certain timeframe regardless of originating class
Why not just use a static class if you only want one instance?
Les goooooo. Hell yeah, more c++ content. 🔥🔥
Man, I honestly don't see why I would use this. I mean, when you understand it, it becomes clear, but the fact is that you _have_ to understand a thing that could really be simpler and shorter.
Am I missing something? Do singletons have any advantages compared to namespaces in C++?
I think that in this case namespaces would be just ugly =P
Tachi Singleton classes can still have constructors and destructors, while namespaces would require you to write and call initialization and shutdown functions. An easy way to demonstrate the advantage of a singleton over a namespace would be a class that logs text to a file, where the constructor and destructor could be used the open and close a handle to the file.
@@hkva1859 I see, you're right. Still, I probably won't use them often
@@Tachi107 That's good, as I think Singleton is vastly overused. It really only makes sense for things that are universally cross cutting, should only have one shared instance, and a plain old global isn't good enough. Think loggers (and even then, I don't think Singleton is worthwhile).
Love this series, more design patterns please!!!!
15:30 what do you mean by static memory?
It's just where static variables are stored. I guess that everything that is in static memory is destroyed at the end of the program, instead of being destroyed at the end of their scope, and that's it.
Great vid,
One of my use cases for Singlton in real life is database connection,
for every request you get, it's better to establish 1 connection to the database, and use it throughout the code, instead of re-establishing connection for every query which will slow down your app.
What's the advantage of being able to create your own variable with a reference to the singleton instance? Why would you ever want to write Singleton& instance = Singleton::Get(); ?
My thought was.. why not put the Get() method in the private sector all together, when all of your reachable method are marked as static anyways?
If you want to access the (same..?) instance again, you will do so by calling ::Get() or just by using the static functions anyway
Thank you so much! Your videos are so good. Thanks to you I learned some little details that are important to know about C++. I would love to see more on idioms. The only idiom everyone seems to use for tutorials is the pimpl idiom.
Thank you The cherno. This is great, just what I need. I wish you can look at more design patterns in future, I mean yuo realyy explain in a way that makes it easy to understand.
I think speaking of Singletons without mentioning dependency injection is somewhat pointless, as you actually covered that without the implementation being derived from somewhere above, the singleton class can be simply replaced by a namespace and have the same functionality.
Since I'm far not a c++ expert, I actually wonder in what ways can a dependency injection implemented in c++. I can imagine ways of doing that, but I don't really think those are good ways, so perhaps covering that part may be good.
BTW You don't need to define static variables in outside the class in c++17 , you can use inline static keyword
Learned a lot from you😊
well, static inline in c++17 does not work for this case, the compiler indicates incomplete error.
i can see some chap on code interview ... " i can name function a "float" ... cherno does it ... "
It would be nice to follow up this with a comparison to the Monostate design pattern.
Cherno you saved my life with this video (again) thx for the great tutorial
I really like your explanation very much, the way you construct the solution makes things more easy, Please add video on all the other class Design Patterns
Superb, Superb , Superb.. Nicely explained..
Can you talk about other Design Patterns that you use in C++?
*My takeaways:*
1. Singleton is a design pattern 0:23
2. What is singleton 2:30, it is a class which you only have one instance
3. An example 7:25
Huh, never thought about using namespace for implementing singletons. Need to try that way of creating it, maybe it have something special in it.
The very best video i'd seen. 🤯 Thanks for all
Please add seperate playlist and videos exclusively explaining design patterns in depth
What about all the other copy/move assignment/constructors? Should we delete them?
Really good! but you are depending on default constructor. what if your class constructor needs some parameters? then how can your get function do it? what I see is the class static instance should be a pointer and not just an object. with pointer you can invoke the required constructor. consider:
#include
using namespace std;
#include
class Point {
public:
static std::unique_ptr& getInstance() {
return instance;
}
static void createInstance(int x, int y)
{
if (!instance)
instance = std::make_unique(Point(x, y));
}
static void releaseInstance()
{
instance.reset();
}
int getX() const {
return this-> x;
}
int getY() const {
return this-> y;
}
void setX(int x) {
this->x = x;
}
void setY(int y) {
this->y = y;
}
private:
static std::unique_ptr instance; // no need to delete copy constructor and copy assignment; this causes them deleted automatically. (if a class has a member whose copy control operations are deleted then this class's also are deleted)
int x;
int y;
Point(int = 0, int = 0);
};
//Initialize pointer to zero so that it can be initialized in first call to createInstance
std::unique_ptr Point::instance = 0;
Point::Point(int a, int b) :
x(a), y(b)
{}
int main()
{
Point::createInstance(10, 20);
std::unique_ptr& pt = pt->getInstance();
cout
What is the difference between doing this and just have a class with entirely static members and methods?
This video is exactly what I needed, it helps me think of how to organize my code better.
Would love to see more design pattern videos!
Have you thought about Vulkan at all or covering it in the future?
The C++ series is back! Hell yeah!
Could you return a pointer to a class too? Or does it have to be a reference?
For the random generator you could have just entered a comment saying // I rolled a dice for this number. I am joking, your channel is great.
Excellent! I finally find some useful C++ tutorial on TH-cam! Thanks!
This is the best C++ playlist on TH-cam, Hope i know it earlier, but i think some topics are missing.
I'm new to c++ but am hoping to use it a bit like c so that not everything is object oriented. Instead of a singleton, could it work as well to simply use global functions inside a namespace? Assuming there is no state that the class is required to have.
I am writing an RNG that generates the numbers on the GPU in the background for my diploma thesis. I considered doing it like this when I first started but I realized that one should be able to initialize multiple instances of RNG in a multithreaded program - one for each thread. I could use a single instance and a mutex, yes, but that would have a huge performance hit, which is the opposite of what I want.
Does marking the copy constructer as delete have to be performed under public:? or could it be done under private: ? would there be consequence of this?
why don't you use the constructor in the get method?
won't simply returning the variable without putting a reference in it cause SegFault?
Is it because, being static it gets initialised with a valid instance?
a database handler a logger are also good examples for singletons
6:53 a singleton is organized global variables
Why are the functions inside the RandomClass namespace static?