前言:
最近在看一些設計模式
看到這篇寫的 c++ 單例模式 感覺挺好挺詳細 我就轉載過來了
自己也寫不出來。。。。
原文鏈接:https://www.cnblogs.com/sunchaothu/p/10389842.html
#include <iostream>
// version1:
// with problems below:
// 1. thread is not safe
// 2. memory leak
class Singleton{
private:
Singleton(){
std::cout<<"constructor called!"<<std::endl;
}
Singleton(Singleton&)=delete;
Singleton& operator=(const Singleton&)=delete;
static Singleton* m_instance_ptr;
public:
~Singleton(){
std::cout<<"destructor called!"<<std::endl;
}
static Singleton* get_instance(){
if(m_instance_ptr==nullptr){
m_instance_ptr = new Singleton;
}
return m_instance_ptr;
}
void use() const { std::cout << "in use" << std::endl; }
};
Singleton* Singleton::m_instance_ptr = nullptr;
int main(){
Singleton* instance = Singleton::get_instance();
Singleton* instance_2 = Singleton::get_instance();
return 0;
}
#include <iostream>
#include <memory> // shared_ptr
#include <mutex> // mutex
// version 2:
// with problems below fixed:
// 1. thread is safe now
// 2. memory doesn't leak
class Singleton{
public:
typedef std::shared_ptr<Singleton> Ptr;
~Singleton(){
std::cout<<"destructor called!"<<std::endl;
}
Singleton(Singleton&)=delete;
Singleton& operator=(const Singleton&)=delete;
static Ptr get_instance(){
// "double checked lock"
if(m_instance_ptr==nullptr){
std::lock_guard<std::mutex> lk(m_mutex);
if(m_instance_ptr == nullptr){
m_instance_ptr = std::shared_ptr<Singleton>(new Singleton);
}
}
return m_instance_ptr;
}
private:
Singleton(){
std::cout<<"constructor called!"<<std::endl;
}
static Ptr m_instance_ptr;
static std::mutex m_mutex;
};
// initialization static variables out of class
Singleton::Ptr Singleton::m_instance_ptr = nullptr;
std::mutex Singleton::m_mutex;
int main(){
Singleton::Ptr instance = Singleton::get_instance();
Singleton::Ptr instance2 = Singleton::get_instance();
return 0;
}
#include <iostream>
class Singleton
{
public:
~Singleton(){
std::cout<<"destructor called!"<<std::endl;
}
Singleton(const Singleton&)=delete;
Singleton& operator=(const Singleton&)=delete;
static Singleton& get_instance(){
static Singleton instance;
return instance;
}
private:
Singleton(){
std::cout<<"constructor called!"<<std::endl;
}
};
int main(int argc, char *argv[])
{
Singleton& instance_1 = Singleton::get_instance();
Singleton& instance_2 = Singleton::get_instance();
return 0;
}
#include <iostream>
class A
{
public:
A() {
std::cout<<"constructor" <<std::endl;
}
~A(){
std::cout<<"destructor"<<std::endl;
}
};
A& ret_singleton(){
static A instance;
return instance;
}
int main(int argc, char *argv[])
{
A& instance_1 = ret_singleton();
A& instance_2 = ret_singleton();
return 0;
}
// brief: a singleton base class offering an easy way to create singleton
#include <iostream>
template<typename T>
class Singleton{
public:
static T& get_instance(){
static T instance;
return instance;
}
virtual ~Singleton(){
std::cout<<"destructor called!"<<std::endl;
}
Singleton(const Singleton&)=delete;
Singleton& operator =(const Singleton&)=delete;
protected:
Singleton(){
std::cout<<"constructor called!"<<std::endl;
}
};
/********************************************/
// Example:
// 1.friend class declaration is requiered!
// 2.constructor should be private
class DerivedSingle:public Singleton<DerivedSingle>{
// !!!! attention!!!
// needs to be friend in order to
// access the private constructor/destructor
friend class Singleton<DerivedSingle>;
public:
DerivedSingle(const DerivedSingle&)=delete;
DerivedSingle& operator =(const DerivedSingle&)= delete;
private:
DerivedSingle()=default;
};
int main(int argc, char* argv[]){
DerivedSingle& instance1 = DerivedSingle::get_instance();
DerivedSingle& instance2 = DerivedSingle::get_instance();
return 0;
}
// brief: a singleton base class offering an easy way to create singleton
#include <iostream>
template<typename T>
class Singleton{
public:
static T& get_instance() noexcept(std::is_nothrow_constructible<T>::value){
static T instance{token()};
return instance;
}
virtual ~Singleton() =default;
Singleton(const Singleton&)=delete;
Singleton& operator =(const Singleton&)=delete;
protected:
struct token{}; // helper class
Singleton() noexcept=default;
};
/********************************************/
// Example:
// constructor should be public because protected `token` control the access
class DerivedSingle:public Singleton<DerivedSingle>{
public:
DerivedSingle(token){
std::cout<<"destructor called!"<<std::endl;
}
~DerivedSingle(){
std::cout<<"constructor called!"<<std::endl;
}
DerivedSingle(const DerivedSingle&)=delete;
DerivedSingle& operator =(const DerivedSingle&)= delete;
};
int main(int argc, char* argv[]){
DerivedSingle& instance1 = DerivedSingle::get_instance();
DerivedSingle& instance2 = DerivedSingle::get_instance();
return 0;
}
#include <iostream>
class A
{
public:
A() {
std::cout<<"constructor" <<std::endl;
}
~A(){
std::cout<<"destructor"<<std::endl;
}
};
template<typename T>
T& get_global(){
static T instance;
return instance;
}
int main(int argc, char *argv[])
{
A& instance_1 = get_global<A>();
A& instance_2 = get_global<A>();
return 0;
}