Inobject-oriented programming, thesingleton pattern is asoftware design pattern that restricts theinstantiation of aclass to a singular instance. It is one of the well-known"Gang of Four" design patterns, which describe how to solve recurring problems in object-oriented software.[1] The pattern is useful when exactly one object is needed to coordinate actions across a system.
More specifically, the singleton pattern allows classes to:[2]
The term comes from themathematical concept of a singleton.
Singletons are often preferred toglobal variables because they do not pollute the globalnamespace (or their containing namespace). Additionally, they permitlazy allocation and initialization, whereas global variables in many languages will always consume resources.[1][3]
The singleton pattern can also be used as a basis for other design patterns, such as theabstract factory,factory method,builder andprototype patterns.Facade objects are also often singletons because only one facade object is required.
Logging is a common real-world use case for singletons, because all objects that wish to log messages require a uniform point of access and conceptually write to a single source.[4]
Implementations of the singleton pattern ensure that only one instance of the singleton class ever exists and typically provideglobal access to that instance.
Typically, this is accomplished by:
The instance is usually stored as a privatestatic variable; the instance is created when the variable is initialized, at some point before when the static method is first called.
ThisC++23 implementation is based on the pre-C++98 implementation in the book[citation needed].
importstd;classSingleton{public:// defines an class operation that lets clients access its unique instance.staticSingleton&get(){// may be responsible for creating its own unique instance.if(nullptr==instance)instance=newSingleton;return*instance;}Singleton(constSingleton&)=delete;// rule of threeSingleton&operator=(constSingleton&)=delete;staticvoiddestruct(){deleteinstance;instance=nullptr;}// existing interface goes hereintgetValue(){returnvalue;}voidsetValue(intvalue_){value=value_;}private:Singleton()=default;// no public constructor~Singleton()=default;// no public destructorstaticSingleton*instance;// declaration class variableintvalue;};Singleton*Singleton::instance=nullptr;// definition class variableintmain(){Singleton::get().setValue(42);std::println("value={}",Singleton::get().getValue());Singleton::destruct();}
The program output is
value=42
This is an implementation of the Meyers singleton[5] in C++11. The Meyers singleton has no destruct method. The program output is the same as above.
importstd;classSingleton{public:staticSingleton&get(){staticSingletoninstance;returninstance;}intgetValue(){returnvalue;}voidsetValue(intvalue_){value=value_;}private:Singleton()=default;~Singleton()=default;intvalue;};intmain(){Singleton::get().setValue(42);std::println("value={}",Singleton::get().getValue());}
A singleton implementation may uselazy initialization in which the instance is created when the static method is first invoked. Inmultithreaded programs, this can causerace conditions that result in the creation of multiple instances. The followingJava 5+ example[6] is athread-safe implementation, using lazy initialization withdouble-checked locking.
publicclassSingleton{privatestaticvolatileSingletoninstance=null;privateSingleton(){}publicstaticSingletongetInstance(){if(instance==null){synchronized(Singleton.class){if(instance==null){instance=newSingleton();}}}returninstance;}}
Some consider the singleton to be ananti-pattern that introducesglobal state into an application, often unnecessarily. This introduces a potential dependency on the singleton by other objects, requiring analysis of implementation details to determine whether a dependency actually exists.[7] This increasedcoupling can introduce difficulties withunit testing.[8] In turn, this places restrictions on any abstraction that uses the singleton, such as preventingconcurrent use of multiple instances.[8][9][10]
Singletons also violate thesingle-responsibility principle because they are responsible for enforcing their own uniqueness along with performing their normal functions.[8]
{{cite book}}
: CS1 maint: multiple names: authors list (link){{cite book}}
: CS1 maint: multiple names: authors list (link)![]() | This article'suse ofexternal links may not follow Wikipedia's policies or guidelines. Pleaseimprove this article by removingexcessive orinappropriate external links, and converting useful links where appropriate intofootnote references.(November 2016) (Learn how and when to remove this message) |