物件導向設計思想

2021-08-25 08:19:08 字數 3442 閱讀 9929

封裝、繼承、多型(既然是設計思想我想設計模式才是主要的)

封裝:public,protect,private

繼承:單繼承(public,private),多重繼承,虛擬繼承

多型:靜態多型(函式過載,模板),動態多型(虛函式)

封裝的目的:隱藏物件的屬性和實現細節,對外提供公開介面。降低和使用者**的耦合,提高安全性,方便**的修改。

例如,如果實現需要修改,只需要修改實現內部的細節,不需要修改使用者**部分。

封裝的訪問級別

public:外部可訪問,子類可訪問,內部可訪問

protect:外部不可訪問,子類可訪問,內部可訪問

private:外部不可訪問(友元可訪問),子類不可訪問,內部可訪問

繼承概念:實現對已有東西的一種共享,某種程度說是一種**復用,增加類與類之間的耦合

單繼承

應用場合:只需要繼承單一的父類,比如四邊形,矩形,正方形

兩種繼承方式的意義

public繼承描述兩個類之間一種is a的關係,能用父類的地方一定能用子類,反之不成立。

private繼承意味著根據某物實現出,這樣可以直接將乙個類的部分功能拿過來用

(直接將乙個類作為復合類也可以實現相同的效果,但是當涉及到protect成員(因為復合類不能直接訪問)

和虛函式的時候(因為復合類不能重寫虛函式,但是作為繼承可以重寫))

多繼承

應用場合:需要繼承多個父類,標準輸入流類,標準輸出流類和標準輸入輸出流類

虛繼承

由於多繼承會造成菱形繼承,即b,c繼承了a,d又繼承了bc,這樣d中就會同時存在兩份a類的子物件資料。為了讓d中只儲存

乙份a的資料,引入了虛繼承。

虛繼承的實現:引入了乙個虛基類的指標,這個指標其實是乙個偏移量,指出公共基類在子類物件中的偏移量。

多型靜態多型主要是編譯時期決定的,因此叫做靜態多型

函式過載——函式名相同,引數不同的一系列函式,在編譯時期可以根據引數的不同決定呼叫哪個函式。

模板——在編譯時期根據類模板或函式模板具現出不同的類和模板實現的多型

動態多型主要發生在執行期

動態多型的實現主要是靠虛函式機制

虛函式——通過相同的指標呼叫函式,但是根據指標所指之物不同,呼叫的函式不同。虛函式給了子類物件一定的靈活性,

他可以選擇繼承父類的介面和實現,也可以選擇只繼承父類的介面,重寫實現。而非虛函式只能同時繼承介面和實現。

虛函式的實現機制:首先明白編譯器為了支援虛函式需要做的事情,然後通過看虛函式被呼叫的過程明白虛函式的作用機制。虛函式怎麼實現的:對於虛函式的支援需要兩個東西,虛函式表和虛函式指標。虛函式表用來存放虛函式的位址。虛函式

指標存放虛函式表的位址。虛函式指標存放在物件內部,在物件被初始化的時候由編譯器完成初始化。首先複製基類的虛函式表,然後對複製的這個表在修改或者新增,修改被子類複寫的函式,替換為響應的子類的函式位址,新增子類新新增的

虛函式的位址。然後再物件初始化的時候將虛函式表的位址放在物件的虛函式指標裡。因此子類和父類的虛函式指標是不一樣的。可以看到在構造虛函式表的過程中,基類和子類中的相同函式在虛函式表中的偏移位置是相同的,並且偏移位置在

編譯時期就可以確定,但是並不能確定的是虛函式指標的值,因為和物件的型別有關,因此要借助執行期型別識別。

虛函式被呼叫的過程是怎樣的

需要首先明白虛函式指標是放在物件起始位置的,在單繼承中,所有繼承體系中的類的虛函式指標都在起始位置,因此所很容易取得。在呼叫虛函式的時候,如果指標所指的物件是基類,那麼取得的虛函式指標所指的是基類的虛函式表,因此

呼叫的將是基類中對應的函式。根據要呼叫的函式可以找到他在虛函式表中對應的位置,取出對應的函式位址,即可完成呼叫如果所指的物件時子類,同理。利用引用來呼叫也是如此。但是如果直接利用物件來呼叫,並不會觸發虛擬機制,而是直

接在編譯器就決定了所呼叫的函式。並且利用指標和引用來呼叫非虛函式也是在編譯時期就決定的。因此要正確的觸發虛擬機制必須同時滿足兩點,利用指標或引用呼叫虛函式。

不同的繼承機制對虛函式機制的影響

單一繼承下面,顯然運作良好,因為虛函式指標都在相同的位置而且只有乙個,可以很容易的取得。但是對於多繼承,為了支援多繼承,物件的記憶體布局中是每個基類含乙個虛函式指標,子類和第乙個基類公用乙個虛函式指標,顯然對於第乙個基

和單一繼承下類似。但是對於後續的基類,要找到對應的虛函式指標必須進行指標的調整,調整到對應的基類所在的位置。可以看到多繼承還是可以支援多型,只是稍微麻煩了一點。對於虛擬繼承,需要根據虛基類指標找到基類然後在找到虛函式

指標再進行呼叫,顯然在虛擬繼承下支援多型比較麻煩,因此一般不把公共基類中存放虛函式。

設計模式

建立性設計模式

工廠模式:將例項的生成交給子類,隱藏建立的細節

例:父類是抽象類,自己不產生物件,呼叫子類產生子類物件進行返回

結構型設計模式

介面卡模式:對已有介面進行變化使其呈現新的功能(功能相似介面不同的類),可以解決**復用和相容性的問題(強調修改介面)

例:stack queue 都是利用deque作為底層容器改變介面之後的介面卡容器

實現:可以用繼承或者復合的方式改變並使用另乙個類的功能(都是根據某物具現出的意思,當然涉及到虛函式和protect的時候只能用繼承)

橋接器模式:將類的功能結構層次(父類子類)和實現結構層次分離(介面實現)分離(應該是實現介面和實現的分離)

實現:分別實現功能層次結構,和實現層次結構,然後再功能層次結構中包含乙個實現層次結構的指標就可以實現兩者的耦合,可以隨時更換他的實現層次結構

行為型設計模式:

迭代器模式:提供遍歷集合中元素的方法,可以將遍歷和資料結構分離

例:stl各種容器的迭代器;

實現:乙個集合就需要乙個迭代器,乙個迭代器類一般都包含乙個集合的引用(所要訪問的集合),然後要實現++ -- 等順序或隨機訪問操作

訪問者模式:在訪問元素的過程中,對元素進行處理,強調的是處理,將資料結構和處理分離

例:for_each 可以對集合中的元素進行統一處理,還可以通過修改仿函式變換處理的方法

模板模式:在父類中定義了流程的框架,在子類中可以根據需要進行重寫

例:(覺得有點像虛函式,好像就是)

物件導向思想設計原則

物件導向思想設計原則 物件導向思想設計原則 在實際的開發中,我們要想更深入的了解物件導向思想,就必須熟悉前人總結過的物件導向的思想的設計原則。單一職責原則 開閉原則 黎克特制替換原則 依賴注入原則 介面分離原則 迪公尺特原則 單一職責原則 其實就是開發人員經常說的 高內聚,低耦合 也就是說,每個類應...

物件導向的設計思想

新設計的板子多加了乙個振鏡控制和雷射器的控制,我畫pcb板的時候是把它們給分開了,就是雷射器控制介面在一起,振鏡控制介面在一起,原本是雷射器和控制雷射移動的位置 振鏡是一對的,我為了佈線方便,就把它們分開了。還發現了乙個問題,就是介面設計得太近了,同時插上兩個公頭的時候就會卡住,只能插上乙個。板子是...

物件導向與面向過程設計思想

設計乙個下棋的遊戲 面向過程的解決方式是分析問題的步驟,然後每個步驟分別用函式來解決。物件導向的解決方式是將他們劃分為若干功能,而不是步驟。1.黑白雙方 2.棋盤系統 繪製棋盤 3.規則系統 判斷輸贏 類與物件的概念 類是對同一事物高度的抽象,類中定義了這一類物件所應具有的靜態屬性 屬性 和動態屬性...