C++使用宏函數(shù)實(shí)現(xiàn)單例模板詳解
在我們?nèi)粘i_發(fā)中,無可避免需要使用單例模式進(jìn)行設(shè)計(jì)類對象,那么實(shí)際上我們寫單例格式基本都是一樣的,那么每次都要寫幾乎一模一樣的代碼來實(shí)現(xiàn)我們需要的單例對象是不是會覺得很累?下面博主提供一種單例模板來完成我們?nèi)粘TO(shè)計(jì)單例類,提高工作效率。既然封裝了,那么當(dāng)然是封裝一個線程安全的單例模板,如下:
ISingleton.hpp
#pragma once #include <stdlib.h> #include <assert.h> #include <thread> #include <mutex> /******************************************************************************/ /**********************ufgnix0802:單例宏定義(線程安全)*************************/ /******************************************************************************/ #define SINGLETON_CLASS_DEFAULT(Class) \ private: \ Class() {} \ ~Class() {} \ Class(Class &other) {} \ Class(const Class &other) {} \ Class& operator=(Class &other) {} \ Class& operator=(const Class &other) {} \ #define SINGLETON_CLASS_FUNC_DECL(Class) \ public: \ static Class& Ins(); \ private: \ static void InitSingleton(); \ \ static void Release(); \ \ SINGLETON_CLASS_DEFAULT(Class) \ private: \ static std::once_flag m_singletonFlag; \ static Class* m_ins; /* https://liam.page/2020/10/27/implement-a-singleton-class-template-in-cxx/ */ /* https://liam.page/2017/01/17/layers-and-operation-system/#CPU-%E5%8A%A8%E6%80%81%E8%B0%83%E5%BA%A6 */ #define SINGLETON_CLASS_FUNC_IMPL(Class) \ Class& Class::Ins() { \ /* 使用雙重檢查,外層檢查是為了避免鎖住過大的面積,從而導(dǎo)致鎖的競爭特別頻繁;*/\ /* 內(nèi)層檢查是為了確保只在其它線程沒有搶占鎖完成初始化工作而設(shè)計(jì)。*/ \ /* 這種做法在Java下是正確的,但是在C++下則沒有保證。*/ \ /* std::once_flag 和 std::call_once:它們內(nèi)部利用互斥量和條件變量組合,*/ \ /* 實(shí)現(xiàn)這樣的語義。值得一提的是,如果執(zhí)行過程中拋出異常,標(biāo)準(zhǔn)庫的設(shè)施不認(rèn)為 */ \ /* 這是一次「成功的執(zhí)行」。于是其他線程可以繼續(xù)搶占鎖來執(zhí)行函數(shù)。 */ \ /* std:call_once確保函數(shù)或代碼片段在多線程環(huán)境下,只需要執(zhí)行一次。 */ \ std::call_once(m_singletonFlag, &Class::InitSingleton); \ assert(m_ins != NULL); \ return *m_ins; \ } \ \ void Class::InitSingleton() { \ m_ins = new Class; \ if (m_ins) { \ /* C 庫函數(shù) int atexit(void (*func)(void)) 當(dāng)程序正常終止時(shí),調(diào)用指定的*/ \ /* 函數(shù)func。您可以在任何地方注冊你的終止函數(shù),*/ \ /* 但它會在程序終止的時(shí)候被調(diào)用。*/ \ ::atexit(Release); \ } \ } \ \ void Class::Release() { \ if (m_ins) { \ delete m_ins; \ m_ins = NULL; \ } \ } #define SINGLETON_CLASS_VARIABLE_IMPL(Class) \ std::once_flag Class::m_singletonFlag; \ Class* Class::m_ins = NULL; #define SINGLETON_CLASS_IMPL(Class) \ SINGLETON_CLASS_VARIABLE_IMPL(Class) \ SINGLETON_CLASS_FUNC_IMPL(Class)
使用方式
注意,如果我們的單例類對象在.hpp文件中那么可能出現(xiàn)重定義的問題,博主設(shè)計(jì)的單例模板,只適用于.h和.cpp,即聲明和定義分開單例類對象。
Aclass.h
#include "ISingleton.hpp" class Aclass { //聲明 SINGLETON_CLASS_FUNC_DECL(Aclass) public: int a; };
Aclass.cpp
#include "Aclass.h" //定義 SINGLETON_CLASS_IMPL(Aclass);
main.c
#include "Aclass.h" int main() { //Aclass a; err Aclass::Ins().a = 5; std::cout << Aclass::Ins().a << std::endl; return 0; }
運(yùn)行結(jié)果:
到此這篇關(guān)于C++使用宏函數(shù)實(shí)現(xiàn)單例模板詳解的文章就介紹到這了,更多相關(guān)C++宏函數(shù)實(shí)現(xiàn)單例模板內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Matlab實(shí)現(xiàn)鯨魚優(yōu)化算法的示例代碼
鯨魚優(yōu)化算法(WOA)是澳大利亞學(xué)者M(jìn)irjaili等于2016年提出的群體智能優(yōu)化算法,根據(jù)座頭鯨的捕獵行為實(shí)現(xiàn)優(yōu)化搜索的目的。本文將利用Matlab實(shí)現(xiàn)這一算法,需要的可以參考一下2022-04-04Qt QCompleter自動補(bǔ)全的實(shí)現(xiàn)
本文主要介紹了Qt QCompleter自動補(bǔ)全的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04解決C語言中使用scanf連續(xù)輸入兩個字符類型的問題
這篇文章主要介紹了解決C語言中使用scanf連續(xù)輸入兩個字符類型的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12C/C++中for語句循環(huán)用法以及練習(xí)舉例
for語句是一種循環(huán)語句,它是對while語句的推廣,下面這篇文章主要給大家介紹了關(guān)于C/C++中for語句循環(huán)用法以及練習(xí)舉例的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03