C++使用宏函數(shù)實現(xiàn)單例模板詳解
在我們?nèi)粘i_發(fā)中,無可避免需要使用單例模式進行設計類對象,那么實際上我們寫單例格式基本都是一樣的,那么每次都要寫幾乎一模一樣的代碼來實現(xiàn)我們需要的單例對象是不是會覺得很累?下面博主提供一種單例模板來完成我們?nèi)粘TO計單例類,提高工作效率。既然封裝了,那么當然是封裝一個線程安全的單例模板,如下:
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() { \
/* 使用雙重檢查,外層檢查是為了避免鎖住過大的面積,從而導致鎖的競爭特別頻繁;*/\
/* 內(nèi)層檢查是為了確保只在其它線程沒有搶占鎖完成初始化工作而設計。*/ \
/* 這種做法在Java下是正確的,但是在C++下則沒有保證。*/ \
/* std::once_flag 和 std::call_once:它們內(nèi)部利用互斥量和條件變量組合,*/ \
/* 實現(xiàn)這樣的語義。值得一提的是,如果執(zhí)行過程中拋出異常,標準庫的設施不認為 */ \
/* 這是一次「成功的執(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)) 當程序正常終止時,調(diào)用指定的*/ \
/* 函數(shù)func。您可以在任何地方注冊你的終止函數(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)重定義的問題,博主設計的單例模板,只適用于.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;
}
運行結果:

到此這篇關于C++使用宏函數(shù)實現(xiàn)單例模板詳解的文章就介紹到這了,更多相關C++宏函數(shù)實現(xiàn)單例模板內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言詳細圖解浮點型數(shù)據(jù)的存儲實現(xiàn)
使用編程語言進行編程時,需要用到各種變量來存儲各種信息。變量保留的是它所存儲的值的內(nèi)存位置。這意味著,當您創(chuàng)建一個變量時,就會在內(nèi)存中保留一些空間。您可能需要存儲各種數(shù)據(jù)類型的信息,操作系統(tǒng)會根據(jù)變量的數(shù)據(jù)類型,來分配內(nèi)存和決定在保留內(nèi)存中存儲什么2022-05-05
使用VScode搭建ROS開發(fā)環(huán)境的教程詳解
這篇文章主要介紹了使用VScode搭建ROS開發(fā)環(huán)境,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
VS?Code+msys2配置Windows系統(tǒng)下C/C++開發(fā)環(huán)境
我們在windows10中使用VS Code做C++程序開發(fā)過程中,需要安裝MSYS2和MinGW,下面這篇文章主要給大家介紹了關于VS?Code+msys2配置Windows系統(tǒng)下C/C++開發(fā)環(huán)境的相關資料,需要的朋友可以參考下2022-12-12

