《C++新經典設計模式》之第7章 單例模式

《C++新經典設計模式》之第7章 單例模式

        • 單例模式.cpp

單例模式.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;}};// 餓漢模式2class 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
{// 懶漢模式1class Singleton1{static Singleton1 *instance;Singleton1() {}~Singleton1() {}public:static Singleton1 *getInstance(){if (instance == nullptr)instance = new Singleton1();return instance;}};Singleton1 *Singleton1::instance = nullptr;// 懶漢模式2class 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;// 懶漢模式5class 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 0using namespace ns1;GameConfig *g_gc1 = GameConfig::getInstance1();GameConfig *g_gc2 = GameConfig::getInstance2();
#endif#if 0using namespace ns2;GameConfig *g_gc = GameConfig::getInstance();// g_gc->freeInstance(); // 手工釋放內存演示
#endif#if 0using namespace ns3;GameConfig *g_gc = GameConfig::getInstance();GameConfig *g_gc2 = GameConfig::getInstance();
#endif#if 0using namespace ns4;GameConfig *g_gc = GameConfig::getInstance();GameConfig *g_gc2 = GameConfig::getInstance();
#endif#if 0using namespace ns5;GameConfig2 *g_gc = GameConfig2::getInstance();GameConfig &g_gc2 = GameConfig::getInstance();myfunc();
#endif#if 0using namespace ns2_1;SingleInstance *s = SingleInstance::GetInstance();s->Print();SingleInstance::GetInstance()->Print();SingleInstance::deleteInstance();
#endif#if 1using 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;
#endifcout << "Over!\n";return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/215581.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/215581.shtml
英文地址,請注明出處:http://en.pswp.cn/news/215581.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

手動搭建koa+ts項目框架(日志篇)

文章目錄 前言一、安裝koa-logger二、引入koa-logger并使用總結如有啟發&#xff0c;可點贊收藏喲~ 前言 本文基于手動搭建koats項目框架&#xff08;路由篇&#xff09;新增日志記錄 一、安裝koa-logger npm i -S koa-onerror and npm i -D types/koa-logger二、引入koa-lo…

【每日一題】【12.11】1631.最小體力消耗路徑

&#x1f525;博客主頁&#xff1a; A_SHOWY&#x1f3a5;系列專欄&#xff1a;力扣刷題總結錄 數據結構 云計算 數字圖像處理 1631. 最小體力消耗路徑https://leetcode.cn/problems/path-with-minimum-effort/這道題目的核心思路是&#xff1a;使用了二分查找和BFS &a…

PHP基礎(2)

目錄 一、PHP 數據類型 二、PHP 字符操作函數 strlen() str_word_count() strrev() strpos() str_replace() 一、PHP 數據類型 PHP 有八種基本數據類型和兩種復合數據類型&#xff1a; 整型&#xff08;int&#xff09;&#xff1a;表示整數&#xff0c;可以是正數或負數&am…

線程Thread源代碼思想學習1

1.啟動線程代碼 public class MultiThreadExample {public static void main(String[] args) {// 創建兩個線程對象Thread thread1 new Thread(new Task());Thread thread2 new Thread(new Task());// 啟動線程thread1.start();thread2.start();} }class Task implements Ru…

EXPLAIN 執行計劃

有了慢查詢語句后&#xff0c;就要對語句進行分析。一條查詢語句在經過 MySQL 查詢優化器的各種基于成本和規則的優化會后生成一個所謂的執行計劃&#xff0c;這個執行計劃展示了接下來具體執行查詢的方式&#xff0c;比如多表連接的順序是什么&#xff0c;對于每個表采用什么訪…

記錄 DevEco 開發 HarmonyOS 應用開發問題記錄 【持續更新】

HarmonyOS 應用開發問題記錄 HarmonyOS 應用開發問題記錄一、預覽器無法成功運行?如何定位預覽器無法編譯問題? 開發遇到的問題 HarmonyOS 應用開發問題記錄 一、預覽器無法成功運行? 大家看到這個是不是很頭疼? 網上能看到許多方案,基本都是關閉一個配置 但是他們并…

InitializingBean初始化--Spring容器管理

目錄 InitializingBean--自動執行一些初始化操作spring初始化bean有兩種方式&#xff1a;1.優點2.缺點2.PostConstruct 注解2.舉例使用InitializingBean接口 和PostConstruct3.初始化交給容器管理4.與main入口函數有什么區別5.在 Spring 中&#xff0c;有兩種主要的初始化 bean…

【Java SE】帶你識別什么叫做異常!!!

&#x1f339;&#x1f339;&#x1f339;個人主頁&#x1f339;&#x1f339;&#x1f339; 【&#x1f339;&#x1f339;&#x1f339;Java SE 專欄&#x1f339;&#x1f339;&#x1f339;】 &#x1f339;&#x1f339;&#x1f339;上一篇文章&#xff1a;【Java SE】帶…

Android獲取Wifi網關

公司有這樣一個應用場景&#xff1a;有一臺球機設備&#xff0c;是Android系統的&#xff0c;它不像手機&#xff0c;它沒有觸摸屏幕&#xff0c;所以我們對球機的操作很不方便&#xff0c;于是我們搞這樣一個設置&#xff1a;點擊球機電源鍵5次分享出一個熱點&#xff0c;然后…

【JVM從入門到實戰】(一) 字節碼文件

一、什么是JVM JVM 全稱是 Java Virtual Machine&#xff0c;中文譯名 Java虛擬機。 JVM 本質上是一個運行在計算機上的程序&#xff0c;他的職責是運行Java字節碼文件。 二、JVM的功能 解釋和運行 對字節碼文件中的指令&#xff0c;實時的解釋成機器碼&#xff0c;讓計算機…

C++類模板不是一開始就創建的,而是調用時生成

類模板中的成員函數和普通類中成員函數創建時機有區別的&#xff1a; 普通類中的成員函數一開始就可以創建模板類中的成員函數調用的時候才可以創建 總結;類模板中的成員函數并不是一開始就創建的&#xff0c;再調用時才去創建 #include<iostream> using namespace st…

微信小程序:模態框(彈窗)的實現

效果 wxml <!--新增&#xff08;點擊按鈕&#xff09;--> <image classimg src"{{add}}" bindtapadd_mode></image> <!-- 彈窗 --> <view class"modal" wx:if"{{showModal}}"><view class"modal-conten…

Vue中$props、$attrs和$listeners的使用詳解

文章目錄 透傳屬性如何禁止“透傳屬性和事件”多根節點設置透傳訪問“透傳屬性和事件” $props、$attrs和$listeners的使用詳解 透傳屬性 透傳屬性和事件并沒有在子組件中用props和emits聲明透傳屬性和事件最常見的如click和class、id、style當子組件只有一個根元素時&#xf…

jOOQ指南中使用的數據庫

jOOQ指南中使用的數據庫 本指南中使用的數據庫將在本節中進行總結和創建 使用Oracle方言來創建 # 創建語言 CREATE TABLE language (id NUMBER(7) NOT NULL PRIMARY KEY,cd CHAR(2) NOT NULL,description VARCHAR2(50) );# 創建作者 CREATE TABLE author (id NUMBER(7) NOT …

mysql:需要準確存儲的帶小數的數據,要使用DECIMAL類型

需要準確存儲的帶小數的數據&#xff0c;要使用DECIMAL&#xff0c;特別是涉及金錢類的業務。而不要使用FLOAT或者DOUBLE。 因為DECIMAL是準確值&#xff0c;不會損失精度。 而FLOAT或者DOUBLE是近似值&#xff0c;會損失精度。 https://dev.mysql.com/doc/refman/8.2/en/fixe…

差生文具多系列之最好看的編程字體

&#x1f4e2;?聲明&#xff1a; &#x1f344; 大家好&#xff0c;我是風箏 &#x1f30d; 作者主頁&#xff1a;【古時的風箏CSDN主頁】。 ?? 本文目的為個人學習記錄及知識分享。如果有什么不正確、不嚴謹的地方請及時指正&#xff0c;不勝感激。 直達博主&#xff1a;「…

數據結構 | Floyd

參考博文&#xff1a; floyd算法 弗洛伊德算法 多源最短路徑算法_弗洛伊德算法例題-CSDN博客

【文心一言】AI試用寫代碼體會:delphi、php

一、前言&#xff1a; 二、讓【文心一言】編寫一個函數 1. Delphi 語言&#xff08;文心一言的回復&#xff09; 2. php 語言&#xff08;文心一言回復&#xff09; 三、總結 一、前言&#xff1a; 眾所周知&#xff0c;chatGPT是可以自動編寫程序的&#xff0c;甚至可以運…

MyBatis緩存機制流程分析

前言 在進行分析之前&#xff0c;建議快速瀏覽之前寫的理解MyBatis原理、思想&#xff0c;這樣更容易閱讀、理解本篇內容。 驗證一級緩存 MyBatis的緩存有兩級&#xff0c;一級緩存默認開啟&#xff0c;二級緩存需要手動開啟。 重復讀取跑緩存 可以看到&#xff0c;第二次…

OpenAI承認GPT-4變懶,即將發布修復方案提升性能

目錄 1OpenAI承認GPT-4變懶&#xff0c;即將發布修復方案提升性能 2一文秒懂人工智能全球近況 1OpenAI承認GPT-4變懶&#xff0c;即將發布修復方案提升性能 **劃重點:** 1. &#x1f92f; 用戶反饋:GPT-4使用者抱怨OpenAI破壞了體驗&#xff0c;稱模型幾乎“害怕”提供答案。…