C++設計模式:單例模式 (現代C++主流實現方式Meyer‘s Singleton + 使用CRTP模板化)

文章目錄

  • 單例模式
  • 創建單例類
  • 餓漢式or懶漢式
  • 現代C++單例模式的主流實現方式——Meyer's Singleton
  • 使用 CRTP 模板化單例類


單例模式

單例模式是指程序中只需要一個實例化對象,在全局作用域或整個代碼架構中,此對象只被實例化一次,就可以達到在整個程序生命周期中被使用的目的。假如程序中設計了單例模式類,但是在程序設計中實例化了多個對象,那么這些對象也只占用同一塊地址空間,在代碼中可以通過"%p"輸出的內存地址看出,這些對象是唯一的實例。

創建單例類

如何保證類的實例有且僅有一個?
涉及一個類多對象操作的函數有以下幾個:

  • 構造函數:創建一個新的對象
  • 拷貝構造函數:根據已有對象拷貝出一個新的對象
  • 拷貝賦值操作符重載函數:兩個對象之間的賦值

為了把一個類可以實例化多個對象的路堵死,可以做如下處理:

  • 構造函數私有化,在類內部只調用一次,這個是可控的。
    • 由于使用者在類外部不能使用構造函數,所以在類內部創建的這個唯一的對象必須是靜態的,這樣就可以通過類名來訪問了,為了不破壞類的封裝,我們都會把這個靜態對象的訪問權限設置為私有的。
      在類中只有它的靜態成員函數才能訪問其靜態成員變量,所以可以給這個單例類提供一個靜態函數用于得到這個靜態的單例對象。
  • 拷貝構造函數私有化或者禁用(使用 = delete)
  • 拷貝賦值操作符重載函數私有化或者禁用(從單例的語義上講這個函數已經毫無意義,所以在類中不再提供這樣一個函數,故將它也一并處理一下。)

在這里插入圖片描述

// 定義一個單例模式的類
class Singleton
{
public:Singleton(const Singleton& obj) = delete;Singleton& operator=(const Singleton& obj) = delete;static Singleton* GetInstance(){return instance;}
private:Singleton() = default;static Singleton* instance;
};//靜態成員變量只能在類外部初始化
Singleton* Singleton::instance = new Singleton();

餓漢式or懶漢式

餓漢模式 就是在類加載的時候立刻進行實例化,這樣就得到了一個唯一的可用對象。
適用于內存大的場景,多線程調用沒有線程安全問題。

懶漢模式 是在類加載的時候不去創建這個唯一的實例,而是在需要使用的時候再進行實例化。
適用于內存緊張的場景,多線程調用有線程安全問題。

參考文章:https://subingwen.cn/design-patterns/singleton/

現代C++單例模式的主流實現方式——Meyer’s Singleton

Meyer’s Singleton是典型的懶漢模式:

  • 線程安全(C++11 起):局部靜態變量的初始化是線程安全的(編譯器會自動加鎖)。
  • 延遲初始化(Lazy Initialization):只有當 GetInstance() 第一次被調用時才會構造對象。
  • 自動資源管理:程序結束時,靜態變量會自動析構(除非你使用了動態分配)。
  • 高效無拷貝:返回的是引用,不會產生拷貝,效率高。
class Singleton
{
public:Singleton(const Singleton& obj) = delete;Singleton& operator=(const Singleton& obj) = delete;static Singleton& GetInstance(){static Singleton instance;return instance;}
private:Singleton() = default;~Singleton() = default;
};

使用 CRTP 模板化單例類

CRTP(Curiously Recurring Template Pattern)奇異遞歸模板模式 是C++中的一個編程技巧,它允許基類使用派生類的類型信息。這種模式在靜態多態、計數器等場景中有應用,例如在LLVM項目中被廣泛使用。通過CRTP,可以避免虛函數調用的開銷,提供更高效和靈活的代碼設計。

CRTP的特性表現為:

  • 基類是一個模板類
  • 派生類繼承該基類時,將派生類自身作為模板參數傳遞給基類

實現一個 模板化的單例類,并使用 CRTP來讓任意類輕松成為單例,可以這樣寫:

template<typename T>
class Singleton
{
protected:Singleton() = default;~Singleton() = default;public:Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;Singleton(Singleton&&) = delete;Singleton& operator=(Singleton&&) = delete;static T& GetInstance(){static T instance;return instance;}
};template<typename T> T& g = Singleton<T>::GetInstance();

使用方式

class MyClass : public Singleton<MyClass>
{friend class Singleton<MyClass>; // 保證 GetInstance 可以訪問構造函數
private:MyClass() { /* 構造邏輯 */ }
public:void DoSomething() { /* ... */ }
};// 使用
MyClass::GetInstance().DoSomething();
// 或
g<MyClass>.DoSomething();

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

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

相關文章

Eureka 和 Nacos

一、基本介紹EurekaEureka 是 Netflix 公司開發的一款基于 REST 風格的服務注冊與發現組件&#xff0c;專為分布式系統設計。它遵循 AP 原則&#xff08;可用性、分區容錯性優先&#xff09;&#xff0c;強調在網絡分區等異常情況下的服務可用性&#xff0c;是 Spring Cloud Ne…

文件IO筆試題

目錄前言一、核心概念&#xff1a;二、關鍵操作步驟&#xff1a;三、為什么需要文件IO&#xff1f;四、常見類型&#xff1a;五、標準IO源碼六、筆試真題和練習1.代碼實現1代碼實現22.代碼實現3.代碼實現4.代碼實現5.代碼實現七、總結前言 文件IO&#xff08;文件輸入/輸出&am…

前端學習 5:DFT

DFT技術 DFT &#xff08;design for testability&#xff09;&#xff1a;指在設計系統和電路的同時&#xff0c;考慮測試的需求&#xff0c;通過增加一定的硬件開銷&#xff0c;獲得最大可測性的設計過程。&#xff08;因為增加了硬件&#xff0c;所以也帶來了不足&#xff…

最長遞增子序列(LIS)問題詳解

最長遞增子序列LIS問題詳解一、問題定義與核心特征1.1 問題描述1.2 核心特征二、基礎解法&#xff1a;動態規劃&#xff08;DP&#xff09;2.1 解法思路2.2 Java代碼實現2.3 復雜度分析三、優化解法&#xff1a;二分查找貪心3.1 核心思路3.2 二分查找的作用3.3 Java代碼實現代碼…

什么是HTTP長連接、短連接?誰更能抗DoS攻擊?

想象你在快餐店點餐&#xff1a; 你&#xff1a;“一個漢堡”收銀員&#xff1a;“好的&#xff0c;15元”交易結束&#xff0c;你離開隊伍你想加杯可樂&#xff0c;重新排隊你&#xff1a;“一杯可樂”收銀員&#xff1a;“好的&#xff0c;8元”再次離開… 這種每次溝通后立即…

微軟徽標認證是什么?如何快速獲取驅動簽名?

在Windows系統中安裝硬件驅動時&#xff0c;是否遇到過“無法驗證發布者”的警告&#xff1f;這正是驅動數字簽名在背后發揮作用。對于軟件開發者而言&#xff0c;驅動數字簽名不僅是系統兼容性的保障&#xff0c;更是企業品牌信任度的核心。一、驅動數字簽名的核心作用驅動數字…

Apache Ignite緩存基本操作

這段內容主要講解了 Apache Ignite 中緩存&#xff08;IgniteCache&#xff09;的基本操作&#xff0c;包括獲取緩存、創建緩存、銷毀緩存、執行原子操作以及異步操作等。下面我將用中文對這些內容進行詳細解釋&#xff0c;幫助你更好地理解。一、獲取緩存實例&#xff08;Gett…

最新基于R語言結構方程模型分析與實踐技術應用

現代統計學理論和方法的不斷完善&#xff0c;使科研工作對統計方法的要求也越來越高&#xff0c;面對紛繁復雜的數據&#xff0c;如何選擇最為合適的數據分析方法已成為科研工作者&#xff0c;尤其是廣大剛處于科研生涯起步階段的研究生們最為棘手問題。隨著科學的發展&#xf…

物聯網_TDengine_EMQX_性能測試

一、Tdengine接口開發文檔 1、數據庫 1.創建數據庫 URL /dp/createdb/ method post 請求示例 {"db_name":"demo01" // 必填 }響應示例 // 成功 {"code": 1,"data": {"成功創建數據庫": "demo04"},"error…

從分析到優化:Amazon Q CLI 助力 EKS 網絡調用鏈剖析與運維實踐

1. 引言 在 Amazon EKS&#xff08;Elastic Kubernetes Service&#xff09;環境中&#xff0c;理解從 ALB&#xff08;Application Load Balancer&#xff09;到 Pod 的完整網絡調用鏈對運維人員至關重要。本文將展示如何利用 Amazon Q CLI 這一 AI 助手工具&#xff0c;通過…

Class10簡潔實現

Class10簡潔實現 import torch from torch import nn from d2l import torch as d2l# 輸入為28*28&#xff0c;輸出為10類&#xff0c;第1、2隱藏層256神經元 num_inputs, num_outputs, num_hiddens1, num_hiddens2 784, 10, 256, 256 # 第1個隱藏層丟棄率為0.2&#xff0c;第…

【多線程篇22】:ConcurrentHashMap的并發安全原理剖析

文章目錄一、HashMap 的“不安全”&#xff1a;問題的根源1. 數據結構回顧 (JDK 1.8)2. 并發下的致命缺陷&#xff1a;put 操作二、ConcurrentHashMap 的安全之道 (JDK 1.8)1. 核心數據結構2. 安全的 put 操作&#xff1a;分場景精細化加鎖3. 安全的 size() 計算&#xff1a;并…

【Java + Vue 實現圖片上傳后 導出圖片及Excel 并壓縮為zip壓縮包】

系統環境&#xff1a; Java JDK&#xff1a;1.8.0_202 Node.js&#xff1a;v12.2.0 Npm&#xff1a;6.9.0 Java后端實現 Controller /*** xxxx-導出* param response 返回信息體* param files 上傳的圖片文件* param param1 參數1* param param2 參數2*/PostMapping("/ex…

安科瑞:能源微電網助力工業園區“綠色”發展

朱以真近日&#xff0c;廈門市工業和信息化局印發工業園區綠色智慧微電網建設&#xff0c;擬開展全市工業園區綠色智慧微電網試點通知&#xff0c;那么對于如何實現綠色園區的建設是今天的話題。對工業園區綠色智慧微電網建設需求&#xff0c;其核心價值體現在“源-網-荷-儲-充…

VUE2 學習筆記3 v-on、事件修飾符、鍵盤事件

事件處理v-on用于事件交互。語法&#xff1a;v-on:要綁定的事件“事件觸發時執行的函數” &#xff08;函數這里可以寫括號&#xff0c;也可以不寫&#xff0c;沒有影響&#xff09;簡寫&#xff1a;:事件觸發時要執行的函數&#xff0c;在Vue配置參數中&#xff0c;通過method…

變換域通訊系統CCSK的matlab仿真

CCSK&#xff08;Cyclic Code Shift Keying&#xff09;通信系統的MATLAB仿真。實現完整的CCSK調制、AWGN信道傳輸和解調過程&#xff0c;并計算了誤碼率&#xff08;BER&#xff09;。 % CCSK通信系統仿真 clear; clc; close all;% 參數設置 L 31; % m序列…

技術演進中的開發沉思-40 MFC系列:多線程協作

今天說說MFC的線程&#xff0c;當年用它實現中間件消息得心應手之時&#xff0c;可以實現一邊實時接收數據&#xff0c;一邊更新界面圖表圖文信息&#xff0c;順滑得讓人想吹聲口哨。 MFC 多線程它像給程序裝上了分身術&#xff0c;讓原本只能 “單任務跑腿” 的代碼&#xff0…

高速公路自動化安全監測主要內容

近年來&#xff0c;隨著社會經濟的快速發展&#xff0c;高速公路的通車里程不斷增加&#xff0c;交通流量日益增大。與此同時&#xff0c;高速公路交通事故數量也呈現出一定的增長趨勢。這些事故不僅造成了大量的人員傷亡和財產損失&#xff0c;還嚴重影響了社會的穩定和經濟的…

完美解決 Ubuntu 中自定義啟動器圖標重復的問題(以 MATLAB 為例)

如果你在 Ubuntu 上為 MATLAB、PyCharm、Android Studio 或其他第三方應用創建了自定義啟動器&#xff0c;并把它固定到了左側的 Dock 欄&#xff0c;你很可能遇到過這個令人抓狂的場景&#xff1a; 當你滿心歡喜地點擊固定的圖標啟動程序后&#xff0c;Dock 欄上竟然“憑空”冒…

一文讀懂深度模型優化器,掌握煉丹工具

深度模型優化器是訓練神經網絡的核心工具&#xff0c;其目標是高效地找到損失函數的最小值。從基礎的隨機梯度下降&#xff08;SGD&#xff09;到結合一階動量修正與兩階段更新的Ranger&#xff0c;優化器的發展始終圍繞著加速收斂、提升穩定性、適應參數差異和增強泛化能力四大…