<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          類的封裝與繼承

          作者: 時(shí)間:2009-12-14 來源:網(wǎng)絡(luò) 收藏


          1 從過程到對象――類概念的引入
          真實(shí)世界是由“對象”組成的,無論是動物、植物、工廠還是機(jī)器等,都是根據(jù)它們的特征,細(xì)分出來的對象類別。盡管在軟件設(shè)計(jì)時(shí),更多時(shí)候我們面對的是經(jīng)過高度抽象化的模型,但最終需要解決的還是真實(shí)世界中的問題。因此,如果能夠在軟件設(shè)計(jì)中按照對象來進(jìn)行建模,將更加契合真實(shí)世界的情況,有利于解決高度復(fù)雜的實(shí)際問題。典型的過程化程序設(shè)計(jì)語言,如,其程序設(shè)計(jì)更傾向于面向過程,以函數(shù)為基本單位。這在自頂向下設(shè)計(jì)方法深入人心的今天,往往有些力不從心,因?yàn)樗茈y恰如其分地模擬真實(shí)世界。
          對于C++語言來說,設(shè)計(jì)的基本單位是類。類是邏輯上相關(guān)的函數(shù)與數(shù)據(jù)的封裝,它是對所要處理的問題的抽象描述。引入了類概念的面向?qū)ο蟪绦蛟O(shè)計(jì)語言C++具有更高的代碼集成度,從而更適合用于大型復(fù)雜程序的開發(fā)。而由類產(chǎn)生的基類、、派生、模板等概念,更是極大地豐富了軟件工程師解決問題的手段。如此強(qiáng)大的概念,如若使用不當(dāng),必然帶來許多意想不到的隱患。為此MISRA C++:2008中專門討論了與類使用相關(guān)的問題,簡單舉例如下。
          規(guī)則10-1-3(強(qiáng)制): 同一層級的某個(gè)基類不允許既是虛基類又是非虛基類。
          這是因?yàn)?,如果一個(gè)基類在多重層次中既是虛類型,又是非虛類型,則在派生出來的相應(yīng)對象中將至少有2個(gè)該基類的子對象拷貝。這可能與開發(fā)人員的理解不一致。為了更好說明這個(gè)問題,請看下面的程序:

          本文引用地址:http://www.ex-cimer.com/article/173524.htm


          上述程序中,由于B1、B2是對A的public virtual,而B3是對A的public繼承。因此,對于C而言,將保有A的2個(gè)子對象拷貝,造成不必要的冗繁,并隱含造成開發(fā)人員誤解的危險(xiǎn)因素。所以,雖然這段程序在語法上是沒有錯(cuò)誤的,但是出于程序安全性角度的考慮,這種使用方法被MISRA C++:2008所禁止。
          我們知道,通過將數(shù)據(jù)(屬性)和函數(shù)(行為)封裝在稱為對象的包中,可以實(shí)現(xiàn)數(shù)據(jù)和函數(shù)的緊密聯(lián)系,構(gòu)成對象對信息的隱藏性。這樣,盡管對象知道怎樣通過定義好的接口實(shí)現(xiàn)相互的通信,但是對象通常并不知道其他對象是怎樣實(shí)現(xiàn)的,對象的細(xì)節(jié)隱藏在對象的內(nèi)部。而同一類對象則具有相同的特點(diǎn),新建立的對象通過繼承現(xiàn)有類的特征而派生出來,同時(shí)可以包含各自獨(dú)有的特點(diǎn)。
          也就是說,“類”很好地解決了2個(gè)問題:程序模塊化封裝的實(shí)現(xiàn),以及合理提高代碼的利用率。對于軟件設(shè)計(jì)者之外的用戶而言,每一個(gè)對象都是給出了特定接口的“黑盒子”;而對于特定的數(shù)據(jù)結(jié)構(gòu),經(jīng)過單一定義之后,就可以借用繼承主體、修改細(xì)節(jié)的手段,來實(shí)現(xiàn)重復(fù)利用。如此高效的統(tǒng)籌兼顧,源于“類”這個(gè)嶄新概念的引入。然而這種高效也需要嚴(yán)格的規(guī)范來保證,否則會帶來意想不到的隱患。為此MISRA C++:2008從類、派生類、成員訪問的控制、特殊的成員函數(shù)以及模板這幾個(gè)方面進(jìn)行了詳細(xì)的討論,并出于安全角度考慮,提出了一系列規(guī)則。下面就結(jié)合MISRA C++:2008中的相關(guān)規(guī)則,對這2個(gè)問題作進(jìn)一步闡述。


          2 統(tǒng)――數(shù)據(jù)與代碼的封裝
          對象的獨(dú)立性是通過封裝實(shí)現(xiàn)的,這是指將抽象得到的數(shù)據(jù)成員和代碼成員相結(jié)合,形成一個(gè)統(tǒng)一的有機(jī)整體,也就是說,將數(shù)據(jù)與操作數(shù)據(jù)的行為進(jìn)行有機(jī)的結(jié)合、統(tǒng)一。
          通過封裝,一部分成員作為類與外部的接口,其他成員則被很好地隱蔽起來,以實(shí)現(xiàn)對數(shù)據(jù)訪問權(quán)限的合理控制,使程序中不同部分之間的相互影響減小到最低。這樣可以達(dá)到增強(qiáng)安全性和簡化程序編寫工作的目的。但是在進(jìn)行封裝時(shí),疏忽一些細(xì)節(jié)可能會得到與程序設(shè)計(jì)者初衷相去甚遠(yuǎn)的結(jié)果,看下面的例子。
          規(guī)則9-3-1(強(qiáng)制): 常量類型的成員函數(shù)不允許返回非常量類型的指針或?qū)︻悢?shù)據(jù)的引用。
          當(dāng)對象被聲明為常量型的類時(shí),只有該類的常量成員函數(shù)能被人們調(diào)用。當(dāng)調(diào)用常量成員函數(shù)時(shí),人們一般認(rèn)為將不會改變對象的狀態(tài)。然而,當(dāng)常量類型的函數(shù)返回1個(gè)指向類數(shù)據(jù)的非常量指針或者對類數(shù)據(jù)的引用時(shí),理論上將允許改變對象的狀態(tài)。這是程序設(shè)計(jì)者不希望看到的。
          作為保護(hù)數(shù)據(jù)、實(shí)現(xiàn)模塊化編程的手段,一個(gè)完全無法被外部訪問的“封裝”是沒有意義的。因此在利用封裝來限制對對象的修改操作時(shí),必須留出必要的“接口”。這些接口通常必須以對象的成員函數(shù)的形式給出,否則可能會破壞封裝的效果。再看下面的例子。
          規(guī)則9-3-2(強(qiáng)制): 成員函數(shù)不允許返回對于類數(shù)據(jù)的非常量的旬柄。
          利用類的成員函數(shù)構(gòu)建類的訪問接口時(shí),可以就對象狀態(tài)是如何被修改的保留更多的控制能力,同時(shí)可以實(shí)現(xiàn)在對類進(jìn)行維護(hù)時(shí)不會受到用戶的影響。返回類數(shù)據(jù)的句柄,將使得用戶可以不經(jīng)過類的接口而對類的狀態(tài)進(jìn)行修改,從而破壞了封裝。


          上一頁 1 2 3 下一頁

          關(guān)鍵詞: 繼承 C語言

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();