




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第C語言也有封裝,繼承和多態(tài)你知道嗎目錄封裝繼承多態(tài)函數(shù)的指針通過函數(shù)的指針實(shí)現(xiàn)多態(tài)總結(jié)我們知道封裝、繼承、多態(tài)是面向?qū)ο蟮娜筇匦?,我們也知道C語言是面向過程的語言,那么可不可以在面向過程的語言中用面向?qū)ο蟮乃枷刖幊棠亍,F(xiàn)在我們就一起看看用C語言如何實(shí)現(xiàn)封裝、繼承、多態(tài)。
封裝
所謂封裝就是把實(shí)現(xiàn)的細(xì)節(jié)隱藏起來,外部只能通過相關(guān)的函數(shù)對一個(gè)類進(jìn)行操作,一呢是方便代碼的復(fù)用,二也可以有效的保證代碼的安全性。那么我們看看Redis源碼中對于雙向鏈表的一個(gè)設(shè)計(jì)和實(shí)現(xiàn),是不是就是傳說中的封裝呢?
typedefstructlistNode{
structlistNode*prev;
structlistNode*next;
void*value;
}listNode;
list*listCreate(){
structlist*list;
list=malloc(sizeof(structlist));
if(list==NULL)returnNULL;
list-head=list-tail=NULL;
list-len=0;
returnlist;
繼承
繼承也是為了代碼的重用設(shè)計(jì)的,比如多個(gè)子類都有一些共同的屬性和方法,那么就可以將這些共同點(diǎn)抽象成一個(gè)父類,讓子類去繼承他,子類也就擁有了父類的特性,更好的實(shí)現(xiàn)了代碼的重用性。但是繼承也有很多缺點(diǎn),比如:
1.java中不能多繼承
2.如果繼承了一個(gè)類,那么就繼承了這個(gè)類的所有public的屬性和方法,即使你不想繼承
3.如果有一天父類的邏輯做了修改,那么子類的邏輯也被迫做了修改
基于這些原因呢,很多時(shí)候是不建議使用繼承的,而是優(yōu)先用組合的方式來達(dá)到代碼的復(fù)用。在Go語言中也沒有extends關(guān)鍵字,也是通過組合實(shí)現(xiàn)代碼的復(fù)用。那么在C語言中,雖然沒有繼承,但是我們可以組合啊,實(shí)現(xiàn)的效果是大同小異的。例如:
structShape{
intarea;
Shape*crateShape();
structRectangle{
structShapeshape;
intwidth;
intheight;
structSquare{
structShapeshape;
intside;
多態(tài)
函數(shù)的指針
這里要回顧一下C語言基礎(chǔ)語法了,先來看看C語言中關(guān)于函數(shù)的指針。如果我們在C語言中定義了一個(gè)函數(shù),那么在編譯的時(shí)候會(huì)把函數(shù)的源代碼編譯成可執(zhí)行的的指令,然后分配一塊內(nèi)存去存放。這段空間的的地址就是函數(shù)的入口地址,每次調(diào)用的時(shí)候會(huì)從該地址入口開始執(zhí)行,函數(shù)名就代表了這個(gè)地址,因此函數(shù)名就是函數(shù)的指針。
那么我們就可以定義一個(gè)用來指向函數(shù)的指針變量,用來存放某一函數(shù)的入口地址。例如:int(*add)(int,int)。這行代碼中第一個(gè)int表示的是返回值類型;(*add)表示add是一個(gè)指針變量,括號不能省略;后面的(int,int)表示參數(shù)類型是兩個(gè)int類型,括號不能省略,括號表示指針變量不是指向其他類型的,而是函數(shù)類型的。之前對函數(shù)的調(diào)用都是通過函數(shù)名,那么現(xiàn)在有了指針變量,我們也可以通過指針變量來對函數(shù)進(jìn)行調(diào)用。
intmain(){
//通過函數(shù)名調(diào)用
max(9,2);
//通過函數(shù)的指針變量調(diào)用
int(*p)(int,int);
//將函數(shù)max的入口地址賦值給指針變量p
p=max();
(*p)(a,b)
intadd(intx,inty){
returnx+y;
通過函數(shù)的指針實(shí)現(xiàn)多態(tài)
我們看下面代碼,ShapeVtbl這個(gè)結(jié)構(gòu)體中定義了一個(gè)計(jì)算面積的函數(shù),沒有實(shí)現(xiàn),我們叫做虛函數(shù)表。Shape這個(gè)結(jié)構(gòu)體中定義了兩個(gè)屬性,一個(gè)vtbl,一個(gè)area。
structShape{
structShapeVtbl*vtbl;
intarea;
structShapeVtbl{
float(*area)(structShape*self);
structRectangle{
structShapeshape;
intwidth;
intheight;
structSquare{
structShapeshape;
intside;
這里我們分別定義了計(jì)算矩形面積的方法rectangle_area和計(jì)算正方形面積的方法square_area。也初始化了兩個(gè)ShapeVtbl,讓他們的函數(shù)指針分別指向不同的函數(shù)入口。那么在實(shí)際運(yùn)行的時(shí)候代碼就會(huì)根據(jù)我們的選擇調(diào)用不同的函數(shù),呈現(xiàn)出多態(tài)的效果。
//計(jì)算矩形面積的方法
floatrectangle_area(structShape*self){
structRectangle*r=(structRectangle*)self;
self-area=r-width*r-height;
returnself-area;
//計(jì)算正方形面積的方法
floatsquare_area(structShape*self){
structSquare*r=(structSquare*)self;
self-area=r-side*r-side;
returnself-area;
//初始化了兩個(gè)ShapeVtbl,讓area函數(shù)分別指向了rectangle_area、square_area
structShapeVtblvtbl1={
rectangle_area,
structShapeVtblvtbl2={
square_area,
//計(jì)算面積的方法,這里的area函數(shù)的邏輯是在運(yùn)行時(shí)期動(dòng)態(tài)綁定的,也就是有self中函數(shù)指針指向的實(shí)際函數(shù)決定的
floatshape_area(structShape*self){
structShapeVtbl*v=self-vtbl;
returnv-area(self);
structSquare*createSquare(){
structSquare*s=malloc(sizeof(structSquare));
s-side=5;
s-shape.vtbl=vtbl2;
intmain(){
structSquare*s=createSquare();
printf("area=%f\n",shape_area((structShape*)s));
更多可以參考圖例:
這樣的設(shè)計(jì)在redis源碼中有很多應(yīng)用,比如redis中的字典,dict結(jié)構(gòu)體定義了字典的基本屬性以及屬于dict的一些特定函數(shù),代碼在dict.h中。
/*
*字典類型特定函數(shù),定義了計(jì)算哈希值、復(fù)制鍵、比較鍵等函數(shù)
typedefstructdictType{
unsignedint(*hashFunction)(constvoid*key);
void*(*keyDup)(void*privdata,constvoid*key);
void*(*valDup)(void*privdata,constvoid*obj);
int(*keyCompare)(void*privdata,constvoid*key1,constvoid*key2);
void(*keyDestructor)(void*privdata,void*key);
void(*valDestructor)(void*privdata,void*obj);
}dictType;
*字典
typedefstructdict{
//類型特定函數(shù)
dictType*type;
void*privdata;
dicththt[2];
intrehashidx;
intiterators;
}dict;
而在redis中,dict的應(yīng)用比較多,鍵的類型也可能有sds、redisObject等多種類型,他們的鍵比較函數(shù),hash函數(shù)等都是不同的,因此有了下面的代碼,分別定義了適應(yīng)于各種鍵的對比、hash等函數(shù),并封裝在了不同的dictType,代碼在redis.c中。那么在實(shí)際應(yīng)用中,只需要為不同的類型選擇不同的dictType即可。
dictTypeclusterNodesBlackListDictType={
dictSdsCaseHash,/*hashfunction*/
NULL,/*keydup*/
NULL,/*valdup*/
dictSdsKeyCaseCompare,/*keycompare*/
dictSdsDestructor,/*keydestructor*/
NULL/*valdestructor*/
/*Migratecachedicttype.*/
dictTypemigrateCacheDictType={
dictSdsHash,/*hashfunction*/
NULL,/*keydup*/
NULL,/*valdup*/
dictSdsKeyCompare,/*keycompare*/
dictSdsDestructor,/*keydestructor*/
NULL/*valdestructor*/
/*Replicationcachedscriptdict(server.repl_scriptcache_dict).
*KeysaresdsSHA1strings,whilevaluesarenotusedatallinthecurrent
*implementation.*/
dictTypereplScriptCacheDictType={
dictSdsCaseHash,/*hashfunction*/
NULL,/*keydup*/
NULL,/*valdup*/
dictSdsKeyCaseCompare,/*keycompare*/
dictSdsDestructor,/*keydestructor*/
NULL/*valdestructor*/
intdictSdsKeyCompare(void*privdat
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- T/CPFIA 0011-2024磷石膏無害化處理指南(試行)
- T/CWAN 0119-2024船用鋼板手持激光填絲角焊推薦工藝規(guī)范
- T/JSGS 018-2024給水排水及灌溉系統(tǒng)用高性能取向硬聚氯乙烯(PVC-O)管材和管件
- 資產(chǎn)經(jīng)營有限公司股權(quán)轉(zhuǎn)讓合同6篇
- 上海保安考試題及答案
- T/CCOA 69-2023半脫脂芝麻
- T/CCOA 64-2023油酸
- T/CEPPEA 5040-2023供配電線路工程竣工驗(yàn)收規(guī)范
- 金蟬脫殼教案設(shè)計(jì)
- 教師任用合同書3篇
- 收集土木APS例題及資料
- 人教版(2025新版)七年級下冊數(shù)學(xué)第七章 相交線與平行線 單元測試卷(含答案)
- “崗課賽證”綜合育人模式下高職活頁式教材的建設(shè)研究
- 2025年中鋁物資有限公司招聘筆試參考題庫含答案解析
- 【MOOC】《研究生英語科技論文寫作》(北京科技大學(xué))中國大學(xué)MOOC慕課答案
- 寄生蟲病診斷與治療
- 智研咨詢發(fā)布-2024年中國室內(nèi)定位技術(shù)行業(yè)市場運(yùn)行態(tài)勢及發(fā)展趨勢預(yù)測報(bào)告
- 現(xiàn)場服務(wù)合同模板
- 《專利檢索與撰寫》課程教學(xué)大綱
- 糖尿病視網(wǎng)膜病變專家共識
- “雄鷹杯”全國小動(dòng)物醫(yī)師技能大賽考試題庫(660題)
評論
0/150
提交評論