《C++新经典设计模式》之第7章 单例模式
2023-12-13 05:49:24
《C++新经典设计模式》之第7章 单例模式
单例模式.cpp
#include <iostream>
#include <memory>
#include <mutex>
#include <vector>
#include <atomic>
using namespace std;
// 懒汉式,未释放
namespace ns1
{
class GameConfig
{
static GameConfig *m_instance1; // 指向本类对象的指针
// static mutex m_mutex;
// static shared_ptr<GameConfig> GameConfig::m_instance3;
private:
GameConfig(){};
GameConfig(const GameConfig &tmpobj);
GameConfig &operator=(const GameConfig &tmpobj);
~GameConfig(){};
public:
static GameConfig *getInstance1()
{
// lock_guard<mutex> l(m_mutex);
if (m_instance1 == nullptr)
m_instance1 = new GameConfig();
return m_instance1;
}
static GameConfig *getInstance2()
{
static GameConfig m_instance2;
return &m_instance2;
}
/*
static shared_ptr<GameConfig> getInstance3()
{
if (m_instance3 == nullptr)
m_instance3 = make_shared<GameConfig>();
return m_instance3;
}
*/
/*
static shared_ptr<GameConfig> getInstance4()
{
static shared_ptr<GameConfig> m_instance4(new GameConfig());
return m_instance4;
}
*/
};
GameConfig *GameConfig::m_instance1 = nullptr;
// mutex GameConfig::m_mutex;
// shared_ptr<GameConfig> GameConfig::m_instance3 = nullptr;
}
// 懒汉式,嵌套类释放
namespace ns2
{
class GameConfig
{
static GameConfig *m_instance;
// static mutex m_mutex;
private:
GameConfig(){};
GameConfig(const GameConfig &tmpobj);
GameConfig &operator=(const GameConfig &tmpobj);
~GameConfig(){};
public:
static GameConfig *getInstance()
{
// lock_guard<mutex> gcguard(m_mutex);
if (m_instance == nullptr)
{
// 这里再加锁
// lock_guard<mutex> gcguard(m_mutex);
// if (m_instance == nullptr)
//{
m_instance = new GameConfig();
static Garbo garboobj;
//}
}
return m_instance;
}
public:
static void freeInstance() // 要手工调用才能释放内存
{
if (GameConfig::m_instance != nullptr)
{
delete GameConfig::m_instance;
GameConfig::m_instance = nullptr;
}
}
private:
class Garbo // 手工释放单件类对象引入的GameConfig类中的嵌套类(垃圾回收)
{
public:
~Garbo() { GameConfig::freeInstance(); }
};
};
GameConfig *GameConfig::m_instance = nullptr;
// mutex GameConfig::m_mutex;
}
// 懒汉式,加锁+嵌套类释放
namespace ns3
{
class GameConfig
{
static atomic<GameConfig *> m_instance;
static mutex m_mutex;
private:
GameConfig(){};
GameConfig(const GameConfig &tmpobj);
GameConfig &operator=(const GameConfig &tmpobj);
~GameConfig(){};
public:
static GameConfig *getInstance()
{
GameConfig *tmp = m_instance.load(memory_order_relaxed);
atomic_thread_fence(memory_order_acquire);
if (tmp == nullptr)
{
lock_guard<mutex> lock(m_mutex);
tmp = m_instance.load(memory_order_relaxed);
if (tmp == nullptr)
{
tmp = new GameConfig();
static Garbo garboobj;
atomic_thread_fence(memory_order_release);
m_instance.store(tmp, memory_order_relaxed);
}
}
return tmp;
}
private:
class Garbo // 手工释放单件类对象引入的GameConfig类中的嵌套类(垃圾回收)
{
public:
~Garbo()
{
if (GameConfig::m_instance != nullptr)
{
delete GameConfig::m_instance;
GameConfig::m_instance = nullptr;
}
}
};
};
atomic<GameConfig *> GameConfig::m_instance;
mutex GameConfig::m_mutex;
}
// 饿汉式,嵌套类释放
namespace ns4
{
class GameConfig
{
static GameConfig *m_instance;
private:
GameConfig(){};
GameConfig(const GameConfig &tmpobj);
GameConfig &operator=(const GameConfig &tmpobj);
~GameConfig(){};
public:
static GameConfig *getInstance() { return m_instance; }
private:
class Garbo // 手工释放单件类对象引入的GameConfig类中的嵌套类(垃圾回收)
{
public:
~Garbo()
{
if (GameConfig::m_instance != nullptr)
{
delete GameConfig::m_instance;
GameConfig::m_instance = nullptr;
}
}
};
private:
static Garbo garboobj;
};
GameConfig *GameConfig::m_instance = new GameConfig(); // 趁静态成员变量定义的时机直接初始化是被允许的,即便GameConfig构造函数用private修饰
GameConfig::Garbo GameConfig::garboobj;
}
// 饿汉式
namespace ns5
{
class GameConfig2
{
static GameConfig2 m_instance;
private:
GameConfig2(){};
GameConfig2(const GameConfig2 &tmpobj);
GameConfig2 &operator=(const GameConfig2 &tmpobj);
~GameConfig2(){};
public:
static GameConfig2 *getInstance() { return &m_instance; }
};
GameConfig2 GameConfig2::m_instance;
class GameConfig
{
private:
GameConfig(){};
GameConfig(const GameConfig &tmpobj);
GameConfig &operator=(const GameConfig &tmpobj);
~GameConfig(){};
public:
static GameConfig &getInstance()
{
static GameConfig instance;
return instance;
}
};
int myfunc()
{
static int stcs = 100; // 不需要调用myfunc函数,stcs就已经等于100了
stcs += 180;
return stcs;
}
}
// 饿汉式
namespace ns111
{
// 饿汉模式
class CSingleton
{
CSingleton() {}
~CSingleton() {}
public:
static CSingleton *GetInstance()
{
static CSingleton instance;
return &instance;
}
};
// 饿汉模式2
class CSingleton2
{
static CSingleton2 *instance;
CSingleton2() {}
~CSingleton2() {}
public:
static CSingleton2 *GetInstance()
{
return instance;
}
};
CSingleton2 *CSingleton2::instance = new CSingleton2();
// 饿汉模式3,智能指针
class CSingleton3
{
static shared_ptr<CSingleton3> instance;
CSingleton3() {}
~CSingleton3() {}
public:
static shared_ptr<CSingleton3> GetInstance()
{
return instance;
}
static void destoryInstance(CSingleton3 *x)
{
delete x;
}
};
shared_ptr<CSingleton3> CSingleton3::instance(new CSingleton3(), destoryInstance);
// 饿汉模式4,静态嵌套类
class CSingleton4
{
static CSingleton4 *instance;
class Deleter
{
public:
~Deleter()
{
if (instance != nullptr)
{
delete instance;
instance = nullptr;
}
}
};
static Deleter m_deleter;
CSingleton4() {}
~CSingleton4() {}
public:
static CSingleton4 *GetInstance() { return instance; }
};
CSingleton4 *CSingleton4::instance = new CSingleton4();
CSingleton4::Deleter CSingleton4::m_deleter;
}
namespace ns222
{
// 懒汉模式1
class Singleton1
{
static Singleton1 *instance;
Singleton1() {}
~Singleton1() {}
public:
static Singleton1 *getInstance()
{
if (instance == nullptr)
instance = new Singleton1();
return instance;
}
};
Singleton1 *Singleton1::instance = nullptr;
// 懒汉模式2
class Singleton2
{
static Singleton2 *m_instance;
static mutex mtx;
Singleton2() {}
~Singleton2() {}
public:
Singleton2(const Singleton2 &) = delete;
Singleton2 &operator=(const Singleton2 &) = delete;
public:
static Singleton2 *getInstance()
{
if (NULL == m_instance)
{
unique_lock<mutex> lock(mtx);
if (NULL == m_instance)
m_instance = new Singleton2();
}
return m_instance;
}
};
Singleton2 *Singleton2::m_instance = nullptr;
mutex Singleton2::mtx;
// 懒汉模式3,智能指针
class Singleton3
{
static shared_ptr<Singleton3> m_instance;
static mutex mtx;
Singleton3() {}
~Singleton3() {}
public:
Singleton3(const Singleton3 &) = delete;
Singleton3(Singleton3 &&) = delete;
Singleton3 &operator=(const Singleton3 &) = delete;
Singleton3 &operator=(Singleton3 &&) = delete;
public:
static void destoryInstance(Singleton3 *x) { delete x; }
static shared_ptr<Singleton3> getInstance()
{
if (NULL == m_instance)
{
lock_guard<mutex> lock(mtx);
if (NULL == m_instance)
m_instance.reset(new Singleton3(), destoryInstance);
}
return m_instance;
}
};
shared_ptr<Singleton3> Singleton3::m_instance = nullptr;
mutex Singleton3::mtx;
// 懒汉模式4,静态嵌套类
class Singleton4
{
static Singleton4 *m_instance;
static mutex mtx;
Singleton4() {}
~Singleton4() {}
class Deleter
{
public:
~Deleter()
{
if (m_instance != nullptr)
{
delete m_instance;
m_instance = nullptr;
}
}
};
static Deleter m_deleter;
public:
Singleton4(const Singleton4 &) = delete;
Singleton4 &operator=(const Singleton4 &) = delete;
public:
static Singleton4 *getInstance()
{
if (NULL == m_instance)
{
lock_guard<mutex> lock(mtx);
if (NULL == m_instance)
m_instance = new Singleton4();
}
return m_instance;
}
};
Singleton4 *Singleton4::m_instance = nullptr;
mutex Singleton4::mtx;
Singleton4::Deleter Singleton4::m_deleter;
// 懒汉模式5
class Singleton5
{
static atomic<Singleton5 *> m_instance;
static mutex mtx;
Singleton5() {}
~Singleton5() {}
public:
Singleton5(const Singleton5 &) = delete;
Singleton5 &operator=(const Singleton5 &) = delete;
public:
static Singleton5 *getInstance()
{
Singleton5 *p = m_instance;
if (p == nullptr)
{
lock_guard<mutex> ll{mtx};
if ((p = m_instance) == nullptr)
m_instance = p = new Singleton5();
}
return m_instance;
}
};
atomic<Singleton5 *> Singleton5::m_instance{nullptr};
mutex Singleton5::mtx;
}
// 加锁的懒汉式
namespace ns2_1
{
class SingleInstance
{
private:
static SingleInstance *m_SingleInstance;
static mutex m_Mutex;
private:
SingleInstance() {}
~SingleInstance() {}
SingleInstance(const SingleInstance &signal) {}
const SingleInstance &operator=(const SingleInstance &signal) {}
public:
static SingleInstance *GetInstance()
{
if (m_SingleInstance == nullptr)
{
unique_lock<mutex> lock(m_Mutex); // 加锁
if (m_SingleInstance == nullptr)
{
volatile auto temp = new (nothrow) SingleInstance();
m_SingleInstance = temp;
}
}
return m_SingleInstance;
}
static void deleteInstance()
{
unique_lock<mutex> lock(m_Mutex); // 加锁
if (m_SingleInstance)
{
delete m_SingleInstance;
m_SingleInstance = nullptr;
}
}
void Print() { cout << "实例内存地址: " << this << endl; }
};
SingleInstance *SingleInstance::m_SingleInstance = nullptr;
mutex SingleInstance::m_Mutex;
}
namespace ns2_2
{
class Singleton
{
static shared_ptr<Singleton> singleton;
static mutex singletonMutex;
public:
static shared_ptr<Singleton> getSingleton()
{
if (singleton == nullptr)
{
unique_lock<mutex> lock(singletonMutex);
if (singleton == nullptr)
singleton.reset(new Singleton());
}
return singleton;
}
void print() { cout << "Hello World." << endl; }
~Singleton() { cout << __PRETTY_FUNCTION__ << endl; }
private:
Singleton() { cout << __PRETTY_FUNCTION__ << endl; }
};
shared_ptr<Singleton> Singleton::singleton = nullptr;
mutex Singleton::singletonMutex;
}
namespace ns2_3
{
class Singleton
{
static shared_ptr<Singleton> singleton;
static once_flag singletonFlag;
private:
Singleton() {}
// public:
// ~Singleton() {}
public:
void print() { cout << "Hello World." << endl; }
public:
static shared_ptr<Singleton> getSingleton()
{
call_once(singletonFlag, [&]
{ singleton.reset(new Singleton()); });
return singleton;
}
};
shared_ptr<Singleton> Singleton::singleton = nullptr;
once_flag Singleton::singletonFlag;
}
// 模板实现
namespace ns2_4
{
template <typename T>
shared_ptr<T> getInstance()
{
static shared_ptr<T> instance(new T());
return instance;
}
class TestClass
{
public:
TestClass() { cout << "TestClass constructed!" << endl; }
void print() { cout << "TestClass Address: " << this << endl; }
};
}
namespace ns22222
{
class Single
{
private:
Single() {}
//~Single() {}
static shared_ptr<Single> instance;
Single(const Single &);
Single &operator=(const Single &);
public:
static Single &getInstance()
{
if (instance == nullptr)
instance.reset(new Single());
return *instance;
}
};
shared_ptr<Single> Single::instance = nullptr;
class SingleObject
{
static shared_ptr<SingleObject> instance;
SingleObject() {}
// public:
//~SingleObject() {}
public:
static shared_ptr<SingleObject> getInstance() { return instance; }
void showMessage() { cout << "Hello World!" << endl; }
};
shared_ptr<SingleObject> SingleObject::instance(new SingleObject());
}
int main()
{
#if 0
using namespace ns1;
GameConfig *g_gc1 = GameConfig::getInstance1();
GameConfig *g_gc2 = GameConfig::getInstance2();
#endif
#if 0
using namespace ns2;
GameConfig *g_gc = GameConfig::getInstance();
// g_gc->freeInstance(); // 手工释放内存演示
#endif
#if 0
using namespace ns3;
GameConfig *g_gc = GameConfig::getInstance();
GameConfig *g_gc2 = GameConfig::getInstance();
#endif
#if 0
using namespace ns4;
GameConfig *g_gc = GameConfig::getInstance();
GameConfig *g_gc2 = GameConfig::getInstance();
#endif
#if 0
using namespace ns5;
GameConfig2 *g_gc = GameConfig2::getInstance();
GameConfig &g_gc2 = GameConfig::getInstance();
myfunc();
#endif
#if 0
using namespace ns2_1;
SingleInstance *s = SingleInstance::GetInstance();
s->Print();
SingleInstance::GetInstance()->Print();
SingleInstance::deleteInstance();
#endif
#if 1
using namespace ns2_4;
getInstance<TestClass>()->print();
getInstance<TestClass>()->print();
auto instance1 = getInstance<vector<int>>();
auto instance2 = getInstance<vector<int>>();
instance1->push_back(1);
instance2->push_back(2);
cout << "instance1->size(): " << instance1->size() << endl;
cout << "instance2->size(): " << instance2->size() << endl;
cout << "instance1 address: " << instance1.get() << endl;
cout << "instance2 address: " << instance2.get() << endl;
#endif
cout << "Over!\n";
return 0;
}
文章来源:https://blog.csdn.net/oqqyx1234567/article/details/128665714
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!