面向对象设计思想-C语言
? ? 面向?qū)ο蟮娜齻€特征:封裝,繼承,多態(tài)。但是C語言不是面向?qū)ο缶幊陶Z言,所以需要借助一些技巧來實(shí)現(xiàn)這三個特征:
(1)C語言沒有成員函數(shù),struct只能封裝數(shù)據(jù),不能封裝方法,可以在struct里使用函數(shù)指針;
(2)C語言不支持繼承,可以在一個struct里包含另一個struct;
(3)C語言也沒有虛函數(shù),實(shí)現(xiàn)多態(tài)就更麻煩了,我不會。舉個例子:現(xiàn)在有Point結(jié)構(gòu)體定義如下:
struct Point{float x; ?float y; };? ?如果想從Point派生出Circle,可以這么寫:
struct Circle{ ?struct Point o; //圓心??float?r;????????//半徑}; struct Circle C;struct?Point?*pPoint?=?(struct?Point*)(&C);?????此時如果將Circle類型的指針強(qiáng)制換換成Point類型指針,因?yàn)閮?nèi)存是順序連續(xù)的,所以沒問題,pPoint->x訪問的是C.o.x,pPoint->y訪問的是C.o.y.也就是說在需要基類指針的地方可以傳入派生類的指針。
????但是如果將o和r的順序換一下就錯了。
struct Circle{??float?r;????????//半徑??struct?Point?o;?//圓心}; struct Circle C;struct?Point?*pPoint?=?(struct?Point*)(&C);//這么轉(zhuǎn)會出問題????簡單來說就是如果想使用C語言的繼承,那么基類對象一定要寫在派生類的最前面!但是對C語言編程而言,不建議使用繼承和多態(tài),使用封裝就可以了。對封裝的理解可以退化為:不直接訪問結(jié)構(gòu)體的成員變量而是通過函數(shù)去訪問(C語言沒有private屬性,直接訪問成員變量總是可以的,但是不建議這么做);此外C語言結(jié)構(gòu)體沒有this指針,所以使用函數(shù)指針封裝方法也用的比較少,更多的是提供一些全局函數(shù),將結(jié)構(gòu)體指針作為參數(shù)傳進(jìn)去操作。
????假設(shè)有個Moubus數(shù)據(jù)包的結(jié)構(gòu)體:
#define PACK_SIZE 256 struct ModbusPack{ ?uint8_t data[PACK_SIZE]; ?uint8_t len;};還有和它對應(yīng)的操作函數(shù):
void Modbus_init(struct ModbusPack *pThis); void Modbus_append(struct ModbusPack *pThis,uint8_t v); void Modbus_appends(struct ModbusPack *pThis,uint8_t *vs,uint8_t len); uint8_t Modbus_len(struct ModbusPack *pThis); void Modbus_append_crc(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);對于Modbus_len這個函數(shù)的實(shí)現(xiàn)如下:
uint8_t?Modbus_len(struct?ModbusPack?*pThis) {//省略對指針是否為空的判斷 ?return pThis->len; }看起來比直接訪問成員變量復(fù)雜,好處在于當(dāng)修改了ModbusPack的實(shí)現(xiàn),將len改為m_len,則只需要修改Modbus_xxx函數(shù)就行了,不影響其他地方對這個函數(shù)的調(diào)用,因?yàn)檎{(diào)用的地方只依賴于這個函數(shù)的名字,而不需要知道相應(yīng)結(jié)構(gòu)體的具體實(shí)現(xiàn)。
struct ModbusPack{ ?uint8_t m_data[PACK_SIZE]; ?uint8_t m_len;}; uint8_t Modbus_len(struct ModbusPack *pThis) { ?//省略對指針是否為空的判斷 ?return pThis->m_len;}簡單的使用例子如下:
#include "modbus.h" int main(){ ?struct ModbusPack pack;??Modbus_init(&pack);//C語言沒有構(gòu)造函數(shù),通過初始化函數(shù)初始化對象 ?Modbus_init_query(&pack,0x01,0x03,0x0000,0x0002); ?Modbus_print(&pack); ?return 0;}運(yùn)行結(jié)果:
友情提示:找對象雖易,面向?qū)ο蟛灰?#xff0c;且行且珍惜。
聲明:
本文于網(wǎng)絡(luò)整理,版權(quán)歸原作者所有,如來源信息有誤或侵犯權(quán)益,請聯(lián)系我們刪除或授權(quán)事宜。
總結(jié)
以上是生活随笔為你收集整理的面向对象设计思想-C语言的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ddos攻击解决方案(ddos解决方案w
- 下一篇: 全车改色备案后能年审吗(全车改色备案)