智能指針之設計模式2

前面介紹了工廠模式控制了智能指針和資源對象的創建過程,現在介紹一下智能指針是如何利用代理模式來實現“類指針(like-pointer)”的功能,并控制資源對象的銷毀過程的。

2、代理模式

代理模式是為其它對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個對象不直接引用另一個對象,而是通過一個代理對象在客戶端和目標對象之間起到中介的作用,這個代理對象提供了和目標對象完全一樣的功能接口,客戶端訪問這個代理對象就像是在訪問目標對象一樣,同時代理對象根據需要在訪問目標對象時進行了控制。智能指針就起到了客戶端和裸指針的中介代理作用。

按照GOF的說法,組成代理模式的角色有:
主題角色(Subject):定義了代理角色和真實角色的共用接口方法,這樣在任何使用真實角色的地方都有可以使用代理角色。
代理角色(Proxy):實現主題角色接口方法,是真實角色的代理,通過真實角色的業務邏輯方法來實現主題角色的接口方法,并可以附加自己的操作,對真實角色的行為進行控制。
真實角色(RealSubject):實現主題角色接口方法,定義了真實角色所要實現的業務邏輯,供代理角色調用。

代理模式的類結構如下圖所示:
在這里插入圖片描述

智能指針使用面向對象技術封裝了C++中的裸指針,是裸指針的包裝類,它按照RAII慣用法來管理指針資源,可以在失去生存期時同時把所管理的資源釋放掉,得益于C++的操作符重載,智能指針提供了*、->等操作符,它的行為就像是指針,可以按照指針的形式來對智能指針對象進行操作,比如使用“*”操作符來解引用所指向的內容,使用“->”操作符來訪問所指向的結構對象的成員,就像是在操作一個普通指針一樣。

我們不妨腦洞大開一下,如果把“指針”當作是一種對象,使用面向對象進行設計的話,可以大體定義成類似下面的class:

template<typename T>
class pointer {
private:T *address; // 數據成員public:pointer(T *p);// 下面是成員函數T *operator++();T *operator--();T *operator+=(int offset);T *operator-=(int offset);T operator*();T operator[int index];T *operator->();delete();
}

再看unique_ptr和shared_ptr類,可以把它們當作是pointer基類的派生類,它們提供了pointer定義的成員方法,并且還包含了一個pointer指針。

以shared_ptr為例,可以視為下面的class:

class shared_ptr : public pointer {
private:pointer ptr; // 資源對象指針,指向被代理對象ref_count *refcnt; // 引用計數
public:shared_ptr(pointer p) {...其它操作ptr = p;}T operator*() {return *ptr;}T *operator->() {return ptr;}~shared_ptr() {...其它操作ptr->delete();}...其它成員函數
}

從類的結構形式上看,shared_ptr類繼承于pointer類,并且擁有一個pointer類型的數據成員,正好符合代理模式的類結構圖:基類pointer對應subject主題類,而shared_ptr類對應proxy代理類,shared_ptr還包含了一個類型為基類pointer的數據成員ptr,即被代理對象,在實踐中就是裸指針。再看shared_ptr的功能,它public繼承了pointer類,因此它對外提供了pointer類的接口,例如解引用操作符*和成員訪問操作符->,當調用shared_ptr的這些接口時,它會把請求轉發到數據成員ptr的對應接口上。同時它也對相關的接口做了控制,比如為了防止訪問內存越界,沒有提供指針的算術運算,更重要的是,它控制了資源對象的生存期管理,比如,只有在引用計數為0時才釋放資源對象,這也正是智能指針的重要功能。也就說,shared_ptr對內包含了一個指針類型成員,對外又表現為一個指針類型,而且還對指針成員的行為做出了控制。這不正是代理模式嗎?

由此可見,智能指針unique_ptr和shared_ptr的實現正是代理模式的典型應用。當然,如果嚴格地按照面向對象編程的特征,因為C++中沒有“指針”類,指針只是C++固有的基本類型,可能不是標準的代理模式,雖然外在形式上不同,但確實表現出了代理模式的思想和意圖:提供了與裸指針相同的功能,并把請求轉發給裸指針處理,同時對裸指針的操作進行了控制(如不提供某種操作,或者限制使用),最核心的控制是能夠對裸指針指向的資源對象進行了生存期管理。

此外,C++中還有另一種形式的“類指針”對象:迭代器,它也實現了*、->等操作符函數,而且還提供了++、–、+=、-=等算術操作符,對照代理模式來分析,它也是使用代理模式來實現的(注:它是標準的迭代器模式,這里關注的是它的“類指針”特性)。不過,智能指針作為指針的代理對象,控制的是被代理對象——指針的生存期管理,而迭代器作為“集合指針”(如指向數組的指針)的代理對象,控制的是對所代理的集合指針的遍歷訪問行為,可以不用關心底層的數據存儲方式,同時控制訪問時不會越界,顯然它的核心功能是指針的算術操作,因為容器里存放的都是對象集合,不止一個,為迭代器提供指針的算術運算操作再正常不過了。

總之,盡管指針在編程使用時,容易發生內存泄漏、指針越界、野指針、重復釋放等錯誤。但是通過它的代理對象-智能指針,可以很好的控制指針的行為,盡可能的避免了一些錯誤的發生。

如果說智能指針使用工廠模式控制了資源對象的創建過程,那它使用代理模式控制了資源對象的銷毀過程:可以控制它在智能對象失去生存期時也立即銷毀資源對象,如unique_ptr,也可以控制它在最后一個引用它的智能指針對象失去生存期時再銷毀,如shared_ptr。

智能指針又是怎樣釋放資源對象的呢?下一篇文章介紹所使用的另一種設計模式。

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

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

相關文章

探索R語言:在線學習資源匯總

一、收集關于特定R主題的問題和答案&#xff08;Q&A&#xff09; 1. Stack overflow Empowering the world to develop technology through collective knowledge – Stack Overflowhttps://stackoverflow.co/ 二、Rstudio工具欄help Rstudio中有個Cheat sheet&#xf…

《C語言中以數組作為參數的探討》

&#x1f680;個人主頁&#xff1a;BabyZZの秘密日記 &#x1f4d6;收入專欄&#xff1a;C語言 &#x1f30d;文章目入 一、數組作為參數的傳遞機制二、數組參數的聲明方式&#xff08;一&#xff09;省略數組大小&#xff08;二&#xff09;指定數組大小&#xff08;三&#x…

深入解析區塊鏈技術:原理、應用與未來展望

1 區塊鏈技術原理 1.1 基本概念 區塊鏈本質上是一個分布式賬本&#xff0c;它由一系列按照時間順序排列的數據塊組成&#xff0c;每個數據塊包含了一定時間內的交易信息。這些數據塊通過密碼學技術相互鏈接&#xff0c;形成一個不可篡改的鏈條。其核心特點包括去中心化、不可篡…

selenium快速入門

一、操作瀏覽器 from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By# 設置選項 q1 Options() q1.add_argument("--no-sandbo…

面試如何應用大模型

在面試中,如果被問及如何應用大模型,尤其是面向政務、國有企業或大型傳統企業的數字化轉型場景,你可以從以下幾個角度進行思考和回答: 1. 確定應用大模型的目標與痛點 首先,明確應用大模型的業務目標,并結合企業的實際需求分析可能面臨的痛點。這些企業通常會關注如何提…

嵌入式常見概念的介紹

目錄 一、MCU、MPU、ARM &#xff08;一&#xff09;MCU&#xff08;微控制器&#xff09; &#xff08;二&#xff09;MPU&#xff08;微處理器&#xff09; &#xff08;三&#xff09;ARM&#xff08;架構&#xff09; 二、DSP &#xff08;一&#xff09;數字信號處理…

深度強化學習(DRL)框架與多目標調度優化詳解

深度強化學習&#xff08;DRL&#xff09;框架與多目標調度優化詳解 &#xff08;截至2025年4月&#xff0c;結合最新研究進展&#xff09; 一、DRL主流框架及核心算法 通用DRL框架 Ray RLlib&#xff1a;支持分布式訓練&#xff0c;集成PPO、A3C、DQN等算法&#xff0c;適用于…

centos 安裝python3.9.9

這里寫自定義目錄標題 安裝編譯依賴 sudo yum -y groupinstall "Development Tools" sudo yum -y install openssl-devel bzip2-devel libffi-devel wget zlib-devel yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel …

【動態規劃】深入動態規劃:背包問題

文章目錄 前言01背包例題一、01背包二、分割等和子集三、目標和四、最后一塊石頭的重量|| 完全背包例題一、完全背包二、 零錢兌換三、零錢兌換||四、完全平方數 前言 什么是背包問題&#xff0c;怎么解決算法中的背包問題呢&#xff1f; 背包問題 (Knapsack problem) 是?種組…

Vue 接口請求 Nginx配置實時壓縮 速度起飛

生效之前 nginx配置如下 gzip on; gzip_min_length 1k; gzip_buffers 16 256k; gzip_http_version 1.1; gzip_comp_level 6; gzip_types application/json application/javascript text/javascript text/css text/plain; gzip_vary on; 生效之后 #user…

Mitosis:跨框架的UI組件解決方案

Mitosis 是一個開源工具&#xff0c;可以將 JSX 組件轉換為 Angular、React、Qwik、Vue、Svelte、Solid 和 React Native 等框架的功能齊全的組件。 Stars 數13019Forks 數593 主要特點 跨框架兼容性&#xff1a;Mitosis 允許開發者編寫一次組件&#xff0c;然后編譯成多個主流…

齊次坐標系統:什么是齊次坐標?為什么要引入齊次坐標?

齊次坐標系統&#xff1a;計算機圖形學的基礎 在計算機圖形學、計算機視覺、相機標定、三維建模等領域&#xff0c;齊次坐標是一個非常重要的數學工具。本文將介紹&#xff1a;齊次坐標的基本概念、數學原理、我們為什么要引入齊次坐標、及其在實際應用中的價值。 文章目錄 齊…

JS的大數運算(注意:原生的只支持整數計算!!!)

JS的大數運算&#xff08;注意&#xff1a;原生的只支持整數計算&#xff01;&#xff01;&#xff01;&#xff09; 一、JS的大數運算&#xff08;注意&#xff1a;原生的只支持整數計算&#xff01;&#xff01;&#xff01;&#xff09;1. 數字精度限制2. 大數解決方案2.1. …

Android 之美國關稅問題導致 GitHub 403 無法正常訪問,責任在誰?

這幾天各國關稅問題導致世界動蕩不安&#xff0c;如今GitHub又無法正常訪問&#xff0c;是不是Google到時候也無法正常使用了。

JAVA中正則表達式的入門與使用

JAVA中正則表達式的入門與使用 一&#xff0c;基礎概念 正則表達式&#xff08;Regex&#xff09; 用于匹配字符串中的特定模式&#xff0c;Java 中通過 java.util.regex 包實現&#xff0c;核心類為&#xff1a; Pattern&#xff1a;編譯后的正則表達式對象。 Matcher&#…

Prompt_Engineering提示詞工程(一)

一、Prompt&#xff08;提示詞&#xff09; Prompt&#xff08;提示詞&#xff09;是給AI模型交互文本片段&#xff0c;用于指導模型生成符合預期輸出結果&#xff0c;提示詞的目的是為模型提供一個上下文的任務&#xff0c;以便模型能夠更準確地理解用戶的意圖&#xff0c;并…

【設計模式】面向對象開發學習OOPC

PLOOC-裸機思維 PLOOC-git OOPC精要——撩開“對象”的神秘面紗 C/C面向對象編程之封裝-KK 面向過程&#xff0c;本質是“順序&#xff0c;循環&#xff0c;分支”面向對象&#xff0c;本質是“繼承&#xff0c;封裝&#xff0c;多態”參考的書籍&#xff1a;《UMLOOPC嵌入式…

軟考高級--案例分析

架構風格 重點 交互方式數據結構控制結構擴展方法 分類 管道-過濾器風格 數據流 數據倉儲風格 星型結構以數據為中心&#xff0c;其他構件圍繞數據進行交互 企業服務總線esb 定義 以一個服務總線充當中間件的角色&#xff0c;把各方服務對接起來&#xff0c;所有服務…

01_背包問題

package org.josh; import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner new Scanner(System.in); int n scanner.nextInt(); // 物品數量 long w scanner.nextLong(); // 背包容量&#xff0c;使用long防止溢出 int[] v …

esp32-idf Linux 環境安裝教程

一、提前說明 1. 系統環境 Ubuntu22.04 2. 適配芯片 ESP32S3 3. idf版本 v5.4.1(截止2025年4月13日為最新版本) 二、安裝步驟 1. 安裝前置依賴 sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev l…