主頁 >  其他 > 一文帶你輕松掌握多種編程范式

一文帶你輕松掌握多種編程范式

2020-12-15 10:21:09 其他

一文帶你輕松掌握多種編程范式

  • 前言
  • 結構化程式的設計
  • 基于物件的程式設計
  • 面向物件的程式設計
  • 基于介面的程式設計
  • 基于介面編程的模板實作

前言

?編程范式有多種,主要有結構化的程式設計思想、基于物件的程式設計思想、面向物件的程式設計思想、基于介面的程式設計思想,那么這些范式各是什么意思呢?別著急,我們通過一個加法器的例子來逐一說明,

結構化程式的設計

?我們來實作一個加法器,在這個加法器中已經保存了被加數,現在需要傳遞加數到加法器,如果你是一個C語言開發,第一反應多半是,這個很簡單啊,用一個結構體來保存被加數,然后再外帶一個加法函式就行了啊
在這里插入圖片描述

?代碼中,結構體Augend保存了加法器的被加數,具體而言,就是由iAugend保存,第9至12行給出了加法函式的定義,該函式接收兩個引數,一是Augend結構體的指標,二是加數iAddend,
? 但這個時候老板來了,他對你說,這個加法器要修改一下,現在需要給被加數添加一個權重值,而且以前的加法器要保留,因為還有一部分代碼要保留它,沒辦法,拿人家的手短,吃人家的嘴軟,繼續當“碼農”吧,既然有一部分代碼要用到老的加法器,那么老的加法器我們還是保留的,這樣一來,就可以按照新的思路來開發新的加法器了,具體的方法如下
在這里插入圖片描述
?可以看到代碼思路同上一個代碼是完全一致的,不同的只是結構體和函式名稱,很顯然,WeightAugend保存了被加數和權重,而WeightAdd則是帶權重的加法函式,好了,現在我們分析一下按照結構化程式設計思想實作的加法器有什么缺陷?學過面向物件的肯定會一口就能說出來,資料和操作這個資料的函式或方法沒有封裝在一起,確切一點就是,這個加法器沒有把被加數、權重以及操作它們的加法運算封裝在一起,另外一個缺陷是什么呢?因為引入帶權重的加法器之后,需要對部分老代碼進行修改,顯然沒有做到代碼封閉,即沒有實作這一變化點的封裝,

基于物件的程式設計

?在物件的世界,任何東西都可以被當成物件,那么按照這個說法,我們需要實作的這個加法器,顯然也是個物件了,用過C++的同學第一反應肯定就是撰寫一個加法器的類,用一個資料成員保存被加數,然后再寫一個public的加法方法就好了,一般就寫成如下這樣
在這里插入圖片描述
?為了防止隱式型別轉換在這里面使用了explicit,同樣的,故事還沒有完,需要實作帶權重的加法運算,但是仍用老代碼來實作Adder類,沒辦法了,我們只有再實作一個帶權重的加法器,依葫蘆畫瓢,WeightingAdder類出爐了,類宣告如下圖:
在這里插入圖片描述
?WeightingAdder類提供了兩個資料成員以分別保存被加數和權重,并提供了帶權重的Add方法,現在我們來比較一下基于物件方法和結構化的差異,那就是封裝,資料和操作這個資料的方法被封裝在了一起,那么在這里,便是被加數或權重、加法運算或帶權重的加法運算,被封裝在了類Adder或WeightingAdder中,只要實體化一個物件來,你就能使用其加法方法,
?一個實際專案中,往往都會有很多的.h檔案和.c檔案來有效組織代碼,如果按照這個思路,通常我們會把結構體Augend的定義放在一個.h檔案中,而Add函式的定義和宣告,則分別放在了一個.c和.h檔案中,這會給加法器的使用者和實作著,帶來一點小麻煩,什么麻煩呢?加法者的使用者,需要不停地查看Augend的頭檔案和Add函式的頭檔案,因為他需要使用結構體的成員,呼叫Add函式;而實作者,也需要不斷地查看Augend頭檔案,如果結構體成員、操作它的函式比較多的話,那這個麻煩比較大,怎么辦呢?很自然地想法就是把Augend結構體和Add函式放在一起好了,這樣管理也比較方便,
在這里插入圖片描述
?上圖代碼中,使用結構體Adder代表加法器,它包含了兩個欄位,一是被加數iAugend,另一個則是函式指標,該函式指標需要指向實際的加法運算函式,顯然這樣一來,就把結構化程式中的結構Augend和Add函式放在了一起,那么這個加法器的使用如下,
在這里插入圖片描述
?在該代碼中,首先24行實體化了adder出來,然后,將Add函式的地址,賦予了pFuncAdd欄位,并進行了被加數的初始化操作,而地29行,則通過pFuncAdd欄位呼叫了加法函式,其實就已經有點像成員函式呼叫了,adder就是物件,pFuncAdd就是成員函式了,但是隨著這種組織結構體和它的操作函式的方式的廣泛應用,很快就會發現一個問題,太麻煩了!只要有一個函式指標欄位,通常就得定義一個函式指標型別,就得在結構體的每一個實體創建后完成函式指標的賦值操作,即系結某個具體的函式,不僅太麻煩還容易出錯,怎么辦呢?交給編譯器算了,把函式的定義或宣告都放在結構體里面,編譯器自己決議,結構體實體創建后,讓編譯器自動系結函式,
?基于物件的方法,同結構化方法的差異,基于物件的方法能夠實作封裝,而這正是結構化方法所欠缺的,之前結構化程式設計思想是分析過,當新增帶權重的加法器時,破壞了代碼的封閉性,即沒能封裝這一變化點,但是,基于物件的思想也不能封裝這一變化點,原本使用的Adder類的老代碼,若要改成使用WeightingAdder類,則必須修改物件創建時的型別、引數傳遞時的型別等,這顯然破壞了代碼的封閉性,由此可見,基于物件的方法,僅在結構化方法的基礎上,彌補了封裝的缺陷,但依然遺留了變化點不能很好封裝的問題,

面向物件的程式設計

?基于物件和面向物件的區別是什么呢?從技術實作角度上來將,很簡單,面向物件多了繼承和虛函式,而這又有什么好處呢?先上代碼
在這里插入圖片描述

?同之前的類相比大致相同,其區別主要是下面幾個方面:

  • Add函式變成了虛函式,這個意圖很明顯,就是希望派生類重寫它
  • m_iAugend資料成員訪問權限變成了protected,這也是保證派生類能訪問它
  • 增加了一個虛解構式,為什么增加呢?因為如果Adder沒有虛解構式,當delete一個型別為Adder的物件指標,但該指標實際指向的其派生類物件時,則派生類的解構式不會被呼叫,
    ? 面向物件版本的Adder寫好了,但是老板說了還需要寫帶權重的加法運算,不過思路清晰多了,讓WeightingAdder從Adder派生吧,代碼如下

在這里插入圖片描述

?很簡單,主要是重寫了虛函式Add,以及引入了權重資料成員,事情看起來已經很完美了,不僅資料和方法封裝在一起,而且代碼的封閉性也做到了,真正是這樣嗎?當然不是,請大家繼續往下看,

基于介面的程式設計

?假設現在需求又改變了,要求普通加法器的被加數必須是非負整數,而帶權重的加法器的被加數,可以是非負的整數,也可以是負的整數,現在Adder類的被加數m_iAugend是int型別的,沒法保障一定是非負的整數,如果把它改成unsigned int,對帶權重的加法器而言,又不能滿足其需求,怎么辦呢?其實一致一來,都存在一個誤區,總是認為應該在普通加法器的基礎上擴展帶權重的加法器,實際上,這兩者除了都是加法器外,大家沒有繼承關系,都是平等的,所以在這里可以考慮這兩個類是兄弟,都是同一個基類加法器,該加法器都提供了加法運算,也就是Add函式,代碼如下
在這里插入圖片描述
?實際上,IAdder是一個介面類,它規定了要成一個加法器所需要實作的介面,即純虛函式Add,顯然Adder類和WeightingAdder類都需要從IAdder類派生,并重寫Add函式,下圖是這兩個類的實作
在這里插入圖片描述

在這里插入圖片描述
?Adder類的被加數m_iAugend是unsigned int型別,滿足被加數為負整數的要求,而這并不影響WeightingAdder類的被加數,同面向物件的方法相比,都封裝資料和操作資料的函式,其次,兩類方法都能封裝既有普通加法器,又有帶權重加法器這一變化點,簡要說明基于介面的方法如何做到這一點的,

void func(IAdder *pAdder)
{
...
   int i = pAdder->Add(5);
}

?同上一節類似,函式func接受IAdder型別的指標,并它通過Adder方法,因此,無論是想使用Adder類的物件還是WeightingAdder類的物件,都只需要向func函式傳遞指標即可,顯然,func函式不用修改一句代碼就能既用Adder類,又使用WeightingAdder類,達到了封裝變化點的要求,但是遇到“普通加法器的被加數,必須是非負的整數,而帶權重的加法器的被加數可以是非負整數,也就是負整數”這一變化點時,面向物件的方法出問題了,根本原因在于繼承,
在這里插入圖片描述

?上圖左邊的類圖是面向物件的類圖,可以看到,面向物件中,WeightingAdder類從Adder類繼承而來,繼承關系是一種強耦合關系,這表現在派生類既耦合于基類的介面,又耦合于基類的實作,而基于介面的設計中,Adder類和WeightingAdder類從父子關系變成了兄弟關系,均從IAdder繼承而來,都是繼承關系,為什么它能解決面向物件方法所不能解決的問題呢?因為此繼承非彼繼承,雖然在基于介面的方法中用到了繼承,但是不是強耦合關系,Adder類和Weighting類都繼承于基類IAdder類,顯然它們都會耦合于基類的介面和實作,但問題是IAdder類實質只有一個純虛函式Add,并沒有任何實作細節,甚至連資料成員都沒有,因此耦合于其實作的說法是沒有意義,所以其耦合度低于面向物件的類結構,這要是基于介面的方法,能封裝型別變化點的原因,

基于介面編程的模板實作

?前面已經利用虛函式,實作了加法器的基于介面的版本,而在本節中,我們利用模板來實作加法器的這一版本,下面直接上代碼

在這里插入圖片描述
?代碼中可以看到,同之前介面類相比多了一個template的帽子,變成了一個類模板,嗯,或者是模板類,類模板和模板類的區別在這里強調一下,**模板類實際上是類模板實體化的一個產物,**很顯然,這里IAdder是個類模板,只要給它不同的模板引數T,就能實體化若干模板類出來,在IAdder實作中,最關鍵的一點就是第19行和第20行,將this指標強轉成型別T的指標,然后再呼叫AddImpl函式,那么這個型別T是什么?AddImpl又從何而來呢?請繼續往下看代碼,
在這里插入圖片描述
在這里插入圖片描述
?上圖中分別給出了普通加法器Adder和帶權加法器WeightingAdder的實作;并且在這兩個類中,都給出了函式AddImpl,從這兩個函式可以看出,它們實作了具體的加法運算,IAdder類模板中的Add函式,呼叫了型別T的AddImpl函式,看來這個AddImpl函式同Adder或WeightingAdder中的AddImpl函式有點關系,什么關系呢?我們通過模板半數演繹來講解,
假設按照下面方式使用加法器

Adder add(5);
adder.Add(4);

?第一行我們實體化了Adder類的一個物件出來,而Adder類的基類即IAdder< Adder>,此時模板引數T實際上就是Adder,而物件adder呼叫Add函式時,Add函式的代碼相當于

int Add(int iAddend)
{
    Adder *pThis = (Adder*)(this);
    pThis->AddImpl(iAddend);

?可以看出,上述代碼中的T被Adder替換掉了,因為此時模板引數T就是Adder,代碼中將this指標,強轉成Adder型別的指標,那么,這個轉換安全嗎?當然,當前的物件即adder,其型別是Adder,因此此時的this指標實際指向的就是Adder類的物件,自己轉成自己,當然是安全的,這種方法能封裝變化點嗎?先看個例子

template<typename T>
void f(IAdder<T> *pAdder)
{
	std::cout << pAdder->Add(4) << std::endl;
}

?當出現需求變化時,例如要增加帶權重的加法器時,即可從IAdder中派生一個WeightingAdder類,并讓模板T等于WeightingAdder,對于上面的f函式而言,若要使用Adder加法器,給它傳遞Adder的物件指標即可,同樣,若要使用WeightingAdder加法器,給它傳遞WeightingAdder物件的指標即可,顯然,f函式的代碼不用做任何修改,因此也實作了變化點,
? 基于模板這種方法所實作的多型,同之前利用虛函式實作多型的區別,主要在于前者是靜態的,由編譯器確定,模板是動態的,運行期才能確定,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/234833.html

標籤:AI

上一篇:K8s根本甩不掉Docker,原因一說就懂

下一篇:Kong APIGW — Overview

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more