www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 芯聞號 > 充電吧
[導讀]    多態(tài)性是C++的一個重要特征。從廣義上說,多態(tài)性是指一段程序能夠處理多種類型對象的能力;具體地講,多態(tài)性就是對不同對象發(fā)出同樣的指令時,不同對象會有不同的行為。    



    多態(tài)性是C++的一個重要特征。從廣義上說,多態(tài)性是指一段程序能夠處理多種類型對象的能力;具體地講,多態(tài)性就是對不同對象發(fā)出同樣的指令時,不同對象會有不同的行為。
    如果程序員充分利用C++的多態(tài)性,設計程序的運行方式會更加靈活多樣,但是會帶來一些暗藏的細節(jié)問題。這些細節(jié)的漏洞也許會通過編譯,但是在某些情況下,不可預測的結果或者背離編程者初衷的結果都會導致程序變得混亂不堪,甚至產生較大的風險。為了規(guī)避這些風險,MISRA C++推薦了一些編程規(guī)則。這些規(guī)則能夠幫助程序員更加完備或者完美地實現(xiàn)多態(tài)性,充分體現(xiàn)C++相比于傳統(tǒng)C語言的一些優(yōu)勢。
    本文主要介紹兩類在實現(xiàn)形式的多態(tài)性中需要注意的一些問題:一是運算符的重載,這是編譯時的多態(tài)性,即程序在編譯時就能根據重載的情況確定需要調用的函數(shù);二是虛函數(shù)的使用,這是運行時的多態(tài)性,即在程序執(zhí)行前,無法根據函數(shù)名和參數(shù)來確定調用哪個函數(shù),必須在程序執(zhí)行過程中,根據執(zhí)行的具體情況來動態(tài)確定。


1 運算符的重載
    運算符重載就是定義某個運算符對于某個類的具體含義。通過運算符的重載,程序員可以針對一些特定的類型使用重載的運算符含義。
    規(guī)則5-2-11(強制):逗號(,),與(&&)以及或(||)運算符不允許被重載。


    如果getValue和setValue的返回類型使用重載運算符&&,則這兩個函數(shù)都需要計算。
    C++的內部規(guī)定是,&&和||都是在已知結果的情況下不再計算后面的值,比如0&&(a--)&&(b++)。然而重載&&運算符和||運算符導致了程序運行時要計算所有的表達式。這對于一些使用&&做判斷的運算來說,會導致一些錯誤。比如getchar()&&putchar(),在讀取文件時,如果讀到文件尾部,即得到getchar()為0時,就不需要再執(zhí)行putchar()了,這樣才能正確地讀取并輸出文件。如果重載&&運算符,那么先需要計算getchar()和putchar()的結果,再執(zhí)行&&運算符的重載定義,這樣可能會導致一些不可知的錯誤。這樣的重載,會導致編譯器在處理&&和||運算符時產生混亂,所以是比較危險的。
    對于逗號表達式來說,默認情況下,編譯器按照逗號表達式規(guī)定的順序計算各個表達式。但是如果重載操作逗號表達式,因為需要先檢查逗號兩邊的表達式類型,來判斷是否使用重載定義的類型,所以會導致計算順序的混亂。這樣比較危險,會產生一些不可知的錯誤。雖然在C++并沒有限制這3個運算符的重載問題,但是從這個例程和MISRA C++的規(guī)則來看,有些時候會產生一些不可預知的錯誤,所以MISRA C++不允許重載上面3個運算符。[!--empirenews.page--]
    規(guī)則5-3-3(強制):單目運算符&不允許被重載。

    
    f1.cc和f2.cc的區(qū)別就在于f1.cc只聲明了A類,而f2.cc包含了A.h。f1.cc僅聲明A類,不會使用A類定義的重載運算,所以f1.cc的8L運算符使用C++內部的取地址定義。f2.cc包含了頭文件A.h,因為A.h包含了A類的完整定義,所以f2.cc的&運算符就會使用用戶定義的重載操作。在同樣一個工程中,僅僅是對A類的聲明不同,就導致了在f2.cc中,&a使用用戶定義的&運算符含義,而在f1.cc中,&a使用C++內部定義的&運算符含義。
    這樣差別會導致程序員在重載&運算符后,無法得知&運算符有沒有使用重載的定義。這樣做是比較危險的,可能會產生與程序員意愿不同的結果。雖然在C++中并沒有限制對單目運算符的重載操作,但是從上面的例程可以看出,MISRA C++不允許重載&運算符是很有必要的。


2 虛函數(shù)的使用
    虛函數(shù)是C++中一類特殊的函數(shù)。在基類中定義一個虛函數(shù),就說明該函數(shù)在派生類中可能有不同的實現(xiàn)方式。當派生類的實例調用這個虛函數(shù)時,首先會在派生類中去查看該函數(shù)有沒有被定義。如果派生類定義了這個函數(shù),則執(zhí)行派生類的函數(shù);否則,在派生路徑上尋找最近的該函數(shù)的定義,并調用該函數(shù)。
    如果從基類派生出多個派生類,那么每個派生類都可以重新定義這個虛函數(shù)。如果通過基類的指針指向派生類的對象,并訪問該虛函數(shù),會對應地調用每個派生類的函數(shù)定義。這樣通過基類類型的指針,就可以使屬于不同派生類的對象產生不同的行為,從而實現(xiàn)了運行過程的多態(tài)。[!--empirenews.page--]
    關于虛函數(shù),MISRA C++有以下幾條規(guī)則:
    規(guī)則10-3-1(強制):在每一個繼承路徑上,虛函數(shù)只能有一個定義。防止按優(yōu)先度調用。
    例外:析構函數(shù)可以定義為虛函數(shù),在每一個派生類上都可以有定義。
    如果一個函數(shù)在同一個類中被聲明為純虛函數(shù),但是還有定義,這樣的定義就會被忽略。

    


    

    
    在例程的后半段是關于按優(yōu)先度調用的解釋,表1顯示的是例程中每個函數(shù)的調用和定義關系。b2.f1()是按照正常的繼承關系來調用foo()函數(shù),并且調用的是V類中foo()的定義。d.f2()和d.f1()都是按照優(yōu)先度調用的。它們雖然最后都是調用了foo()函數(shù),但是經過的繼承路徑卻不相同,而且它們最后只能調用到B1類中foo()的定義。為了防止這種情況發(fā)生,所以Misra C++規(guī)定,虛函數(shù)在一個繼承路徑上,只能有一個函數(shù)定義。



    例程的前半部分描述了多個類的繼承關系,每個類都包括對幾個函數(shù)的定義和聲明。這里簡單介紹一下f1()函數(shù),讀者可以通過表2的內容來理解其他函數(shù)。f1在A類中是虛函數(shù),而且有定義,在C類中有定義,所以當D類繼承C類時,D類中就不能再有定義(“√”表示可以定義,“*”表示不推薦再繼續(xù)定義)。例外是f4,雖然它在A類中有定義,但是因為它是純虛函數(shù),所以它的定義會被忽略。



    這個規(guī)則說明,如果在一個繼承路徑上有兩個函數(shù)定義,在調用函數(shù)時,有可能按照繼承的優(yōu)先度調用函數(shù)。這樣就會導致函數(shù)調用的混亂,可能會調不到程序員希望的函數(shù)。這是在實現(xiàn)多態(tài)時需要特別注意的地方。關于繼承路徑上的函數(shù)定義,C++并沒有明確限制。[!--empirenews.page--]
   從上面的例程可以看出,如果沒有這樣的限制,就會產生一些混亂,雖然程序能夠正常運行,但是不一定能夠按照程序員所設計的方式運行。這樣的運行方式會出現(xiàn)很多漏洞,所以MISRA C++強制規(guī)定在每一個繼承路徑上,虛函數(shù)只能有一個定義。
    規(guī)則10-3-2(強制):每一個重載的虛函數(shù)應該用關鍵字virtual來聲明。

    
    這樣做不需要檢查基類,就可以確定函數(shù)是否為虛函數(shù)。MISRA C++推出這樣的規(guī)則是為了使C++程序更加完善。
    規(guī)則10-3-3(強制):只有被聲明為純虛函數(shù)的虛函數(shù),才能被純虛函數(shù)重載。

    
    foo函數(shù)在A類中定義為純虛函數(shù),在B類中被重載為普通虛函數(shù)。而C類使用純虛函數(shù)重載foo函數(shù)。這樣做是不行的。
    B類中foo函數(shù)重載A類的foo函數(shù)時,是用有定義的虛函數(shù)重載純虛函數(shù),這樣做是可以的。
    C類中的foo函數(shù)重載B類的foo函數(shù)時,是用純虛函數(shù)重載一個非純虛函數(shù),這樣是不行的。在C類中,foo被定義為純虛函數(shù),在C類的對象調用foo函數(shù)時無法調用到B類中的定義。這樣的重載導致B類中對foo函數(shù)的定義丟失。
    所以MISRA C++不允許使用純虛函數(shù)重載非純虛函數(shù),這樣做的目的也是為了使C++程序更加安全。


3 小 結
    正確并完備地實現(xiàn)C++的多態(tài)性,能夠充分發(fā)揮C++的優(yōu)勢,并且提高程序的可讀性和可維護性。如果使用不當,會導致一些想象不到的程序漏洞。MISRA C++針對使用多態(tài)性可能產生的一些漏洞,提出了規(guī)避的方法與建議。本文列出了其中幾條比較關鍵和實用的規(guī)則。關于多態(tài)性的其他規(guī)則,讀者可以查看。MISRA C++(2008),以避免不正確使用多態(tài)性所導致的一些程序漏洞。

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

Java是一門面向對象的編程語言,不僅吸收了C++語言的各種優(yōu)點,還摒棄了C++里難以理解的多繼承、指針等概念,因此Java語言具有功能強大和簡單易用兩個特征。Java語言作為靜態(tài)面向對象編程語言的代表,極好地實現(xiàn)了面向...

關鍵字: Java C++

星標/置頂?公眾號,硬核文章第一時間送達!鏈接|?https://zhuanlan.zhihu.com/p/274473971題很多,先上題后上答案,便于大家思考問題點:1、C和C的特點與區(qū)別?2、C的多態(tài)3、虛函數(shù)實現(xiàn)...

關鍵字: 騰訊 函數(shù) 進程 AI

程序接口是操作系統(tǒng)為用戶提供的兩類接口之一,編程人員在程序中通過程序接口來請求操作系統(tǒng)提供服務。面向過程語言最基本的單元是過程和函數(shù)。

關鍵字: 程序接口 過程 函數(shù)

星標「嵌入式大雜燴」,一起進步!鏈接:https://www.cnblogs.com/jozochen/p/8541714.html一、問題復現(xiàn)穩(wěn)定復現(xiàn)問題才能正確的對問題進行定位、解決以及驗證。一般來說,越容易復現(xiàn)的問...

關鍵字: 嵌入式開發(fā) 函數(shù) 代碼 寄存器

基本上,沒有人會將大段的C語言代碼全部塞入main()函數(shù)。更好的做法是按照復用率高、耦合性低的原則,盡可能的將代碼拆分不同的功能模塊,并封裝成函數(shù)。C語言代碼的組合千變萬化,因此函數(shù)的功能可能會比較復雜,不同的輸入,常...

關鍵字: 函數(shù) PEN C語言代碼 C語言程序

Part1一、讓自己習慣C條款01:視C為一個語言聯(lián)邦C并不是一個帶有一組守則的一體語言:他是從四個次語言(C、Object-OrientedC、Template、STL)?組成的聯(lián)邦政府,每個次語言都有自己的規(guī)約。記住...

關鍵字: TI 函數(shù) ASPECT 編譯器

為什么會寫篇棧變化的文章?做系統(tǒng)分析的話你肯定遇到過一些crash,oops等棘手問題,一般大家都會用gdb,objdump或者addr2line等工具分析pc位置來定位出錯的地方。但是這些分析工具背后的本質原理就不見得...

關鍵字: 函數(shù) ARM C語言 AI

前言:一轉眼從事前端已經6年了,從當時的小白到如今大廠的技術專家,中間也走過不少彎路,從今天開始我會持續(xù)更新前端技術文章,并且整體的文章會進行體系梳理,整個知識體系分為:基礎精講,框架講解,框架及工具原理,前端面試題精講...

關鍵字: 函數(shù) GE FUNCTION APP

關于C的lambda是函數(shù)還是對象,這其實不是一個一概而論的問題。先說結論:對于有捕獲的lambda,其等價于對象。對于沒有任何捕獲的lambda,其等價于函數(shù)!首先,很多C程序員從lambda用法上反推容易發(fā)現(xiàn)是對象,...

關鍵字: 函數(shù)

1.說明在工作過程中,我發(fā)現(xiàn)在實際使用RTOS完成項目時,理解這些知識僅能達到會用RTOS的水平,要想用好RTOS,還需要了解一些比較細節(jié)的機制,否則容易掉坑進去,花大量時間定位問題。本文結合TencentOS-Tiny...

關鍵字: RTOS 函數(shù)

充電吧

89209 篇文章

關注

發(fā)布文章

編輯精選

技術子站

關閉