**:
物件導向的三個特徵:封裝,繼承,多型。但是c語言不是物件導向程式設計語言,所以需要借助一些技巧來實現這三個特徵:
(1)c語言沒有成員函式,struct只能封裝資料,不能封裝方法,可以在struct裡使用函式指標;
(2)c語言不支援繼承,可以在乙個struct裡包含另乙個struct;
(3)c語言也沒有虛函式,實現多型就更麻煩了,我不會。
舉個例子:現在有point結構體定義如下:
如果想從point派生出circle,可以這麼寫:struct point
;
此時如果將circle型別的指標強制換換成point型別指標,因為記憶體是順序連續的,所以沒問題,ppoint->x訪問的是c.o.x,ppoint->y訪問的是c.o.y.也就是說在需要基類指標的地方可以傳入派生類的指標。struct circle
;struct circle c;
struct point *ppoint =
(struct point*)(
&c);
但是如果將o和r的順序換一下就錯了。
簡單來說就是如果想使用c語言的繼承,那麼基類物件一定要寫在派生類的最前面!但是對c語言程式設計而言,不建議使用繼承和多型,使用封裝就可以了。對封裝的理解可以退化為:不直接訪問結構體的成員變數而是通過函式去訪問(c語言沒有private屬性,直接訪問成員變數總是可以的,但是不建議這麼做);此外c語言結構體沒有this指標,所以使用函式指標封裝方法也用的比較少,更多的是提供一些全域性函式,將結構體指標作為引數傳進去操作。struct circle
;struct circle c;
struct point *ppoint =
(struct point*)(
&c);
//這麼轉會出問題
假設有個moubus資料報的結構體:
還有和它對應的操作函式:#define pack_size 256
struct modbuspack
;
對於modbus_len這個函式的實現如下:void
modbus_init
(struct modbuspack *pthis)
;void
(struct modbuspack *pthis,uint8_t v)
;void
(struct modbuspack *pthis,uint8_t *vs,uint8_t len)
;uint8_t modbus_len
(struct modbuspack *pthis)
;void
(struct modbuspack *pthis)
;uint8_t modbus_check
(struct modbuspack *pthis)
;void
modbus_init_query
(struct modbuspack *pthis,uint8_t addr,uint8_t fc,uint16_t regbase,uint16_t regnum)
;void
modbus_print
(struct modbuspack *pthis)
;
看起來比直接訪問成員變數複雜,好處在於當修改了modbuspack的實現,將len改為m_len,則只需要修改modbus_***函式就行了,不影響其他地方對這個函式的呼叫,因為呼叫的地方只依賴於這個函式的名字,而不需要知道相應結構體的具體實現。uint8_t modbus_len
(struct modbuspack *pthis)
簡單的使用例子如下:struct modbuspack
;uint8_t modbus_len
(struct modbuspack *pthis)
#include
"modbus.h"
intmain()
物件導向設計思想
封裝 繼承 多型 既然是設計思想我想設計模式才是主要的 封裝 public,protect,private 繼承 單繼承 public,private 多重繼承,虛擬繼承 多型 靜態多型 函式過載,模板 動態多型 虛函式 封裝的目的 隱藏物件的屬性和實現細節,對外提供公開介面。降低和使用者 的耦合,...
物件導向思想設計原則
物件導向思想設計原則 物件導向思想設計原則 在實際的開發中,我們要想更深入的了解物件導向思想,就必須熟悉前人總結過的物件導向的思想的設計原則。單一職責原則 開閉原則 黎克特制替換原則 依賴注入原則 介面分離原則 迪公尺特原則 單一職責原則 其實就是開發人員經常說的 高內聚,低耦合 也就是說,每個類應...
物件導向的設計思想
新設計的板子多加了乙個振鏡控制和雷射器的控制,我畫pcb板的時候是把它們給分開了,就是雷射器控制介面在一起,振鏡控制介面在一起,原本是雷射器和控制雷射移動的位置 振鏡是一對的,我為了佈線方便,就把它們分開了。還發現了乙個問題,就是介面設計得太近了,同時插上兩個公頭的時候就會卡住,只能插上乙個。板子是...