當(dāng)前位置:首頁 > 公眾號(hào)精選 > wenzi嵌入式軟件
[導(dǎo)讀]本文將敘述 C 的另一個(gè)內(nèi)容,也就是抽象,這也是 C 相對(duì)于 C語言來說獨(dú)特的一點(diǎn)。

前言

在上一則教程中,敘述了關(guān)于C 類型轉(zhuǎn)換的相關(guān)內(nèi)容,在本節(jié)教程中,將敘述?C 的另一個(gè)內(nèi)容,也就是抽象,這也是?C 相對(duì)于?C語言來說獨(dú)特的一點(diǎn),下面我們就來著重?cái)⑹鲞@一點(diǎn)。

純虛函數(shù)

在介紹抽象類之前,需要弄明白何為純虛函數(shù),下面假定我們有這樣一個(gè)需求:

做一個(gè)“各個(gè)國家的人的調(diào)查”,調(diào)查各個(gè)國家的人的:飲食、穿衣、開車

要完成這樣一個(gè)事情,那我們現(xiàn)在就需要實(shí)現(xiàn)這樣幾個(gè)類,一個(gè)是?Human類,其他國家的人從?Human類里派生而來,就比如說是ChineseEnglishman,我們再回過頭來想,我們所要實(shí)現(xiàn)的需求是調(diào)查各個(gè)國家的人,那么這個(gè)過程中,由Human類派生得到?Chinese和?Englishman,那么在實(shí)例化對(duì)象的時(shí)候,我們實(shí)際上是不會(huì)用到Human類去定義一個(gè)對(duì)象的,考慮到這層因素,我們在?Human類里使用到了純虛函數(shù)的概念,類實(shí)現(xiàn)的代碼如下所示:

class?Human
{

private:
????int?a;
public:
????/*純虛函數(shù)*/
????virtual?void?eating(void)?=?0;
????virtual?void?wearing(void)?=?0;
????virtual?void?driving(void)?=?0;
};

class?Englishman?:?public?Human
{
public:
????void?eating(void)??{?cout<<"use?knife?to?eat"<<endl;?}
????void?wearing(void)?{cout<<"wear?english?style"<<endl;?}
????void?driving(void)?{cout<<"drive?english?car"<<endl;?}
};

class?Chinese?:?public?Human?
{
public:
????void?eating(void)??{?cout<<"use?chopsticks?to?eat"<<endl;?}
????void?wearing(void)?{cout<<"wear?chinese?style"<<endl;?}
????void?driving(void)?{cout<<"drive?chinese?car"<<endl;?}
};
我們可以看到在上述的代碼中,Human類的成員函數(shù)跟前幾講所寫的成員函數(shù)有所不同,而如上述?Human類的成員函數(shù)這般寫法,也就被稱之為是純虛函數(shù)

抽象類

上述引出了純虛函數(shù)的寫法,那純虛函數(shù)和抽象類之間有什么關(guān)系呢?實(shí)際上,抽象類就是具有純虛函數(shù)的類,那這抽象類存在的意義是什么呢?總的來說,其作用也就是:向下定義好框架,向上提供統(tǒng)一的接口,其不能夠?qū)嵗瘜?duì)象,基于上述幾個(gè)類的前提下,我們編寫主函數(shù)的代碼:

int?main(int?argc,char?**argv)
{
????Human?h;

????return?0;
}
因?yàn)槌橄箢惒荒軌驅(qū)嵗瘜?duì)象,所以上述代碼編譯結(jié)果是錯(cuò)誤的,錯(cuò)誤信息如下所示:

而使用通過抽象類派生得到的派生類實(shí)例化對(duì)象是可行的,代碼如下所示:

int?main(int?argc,?char**?argv)
{
????Englishman?e;
????Chinese????g;

????return?0;
}
另外需要注意的是:在派生抽象類的過程中,如果派生得到的子類沒有覆寫所有的純虛函數(shù),那么這個(gè)子類還是抽象類,比如有如下所示的代碼,Human類沿用的是上述的寫法,代碼不變,如果我們將上述的?Chinese類進(jìn)行更改,更改后的代碼如下所示:

class?Chinese?:?public?Human?
{
public:
????void?eating(void)?{?cout<<"use?chopsticks?to?eat"<<endl;?}
????void?wearing(void)?{cout<<"wear?chinese?style"<<endl;?}
????//void?driving(void)?{cout<<"drive?chinese?car"<
};
如上述代碼所示,我們將?driving()函數(shù)注釋掉了,那么也就是說,我們并沒有將抽象類的全部純虛函數(shù)進(jìn)行覆寫,那么當(dāng)前這個(gè)Chinese類也是一個(gè)抽象類,也是不能夠進(jìn)行實(shí)例化對(duì)象的,要使得?Chinese類有作用,我們必須派生出來另一個(gè)類,代碼如下所示:

class?Guangximan?:?public?Chinese?
{
????void?driving(void)?{cout<<"drive?guangxi?car"<<endl;?}
};
這個(gè)時(shí)候,就可以用?Guangximan這個(gè)類來實(shí)例化對(duì)象了。

多文件編程

在前面的教程中,有一則教程說到了多文件編程,在?C 中也就是將類的聲明放到頭文件中,將類的實(shí)現(xiàn)放在.cpp文件中,為了更好地闡述這種方法,我們用實(shí)例來進(jìn)行講解,首先,來看一下,所涉及到地所有文件有哪些:

image-20210222103409774
可以看到上述有6個(gè)文件,我們首先來看?Chinese.h這個(gè)文件,代碼如下所示:

#ifndef?_CHINESE_H
#define?_CHINESE_H

#include?
#include?
#include?

using?namespace?std;

class?Chinese
{

public:
????void?eating(void);?
????void?wearing(void);
????void?drivering(void);
};

#endif
通過上述地.h文件可以看出,在這里的Chinese類中,它只涉及到類成員函數(shù)的一個(gè)聲明,并沒有成員函數(shù)的實(shí)現(xiàn),我們繼續(xù)來看Chinese.cpp的類實(shí)現(xiàn):

#include?"Chinese.h"

void?Chinese::eating(void)
{
????cout?<"use?chopsticks?to?eat"?<endl;
}

void?Chinese::wearing(void)
{
????cout?<"wear?chinese?style"?<endl;
}

void?Chinese::drivering(void)
{
????cout?<"driver?china?car"?<endl;
}
按照上述這樣一種方法,我們繼續(xù)來實(shí)現(xiàn)Englishman類中的代碼,首先是Englishman.h中的代碼,代碼如下所示:

#ifndef?_ENGLISHMAN_H
#define?_ENGLISHMAN_H

#include?
#include?
#include?

using?namespace?std;

class?Englishman
{

public:
????void?eating(void);
????void?wearing(void);
????void?driver(void);
};

#endif
繼續(xù)看.cpp中的代碼,代碼如下所示:

#include?"Englishman.h"

void?Englishman::eating(void)
{
????cout?<"use?chopsticks?to?eat"?<endl;
}

void?Englishman::wearing(void)
{
????cout?<"wear?chinese?style"?<endl;
}

void?Englishman::drivering(void)
{
????cout?<"driver?china?car"?<endl;
}
至此,除了主函數(shù)以外的代碼就編寫完了,我們繼續(xù)來看主函數(shù)的代碼:

#include?"Englishman.h"
#include?"Chinese.h"

int?main(int?argc,?char?**argv)
{
????Englishman?e;
????Chinese?c;

????e.eating();
????c.eating();

????return?0;
}
在前面的教程中,我們就說過,如果是多文件的話,需要編寫?Makefile文件,Makefile文件代碼如下:

Human:?main.o?Chinese.o?Englishman.o?Human.o
????g ?-o?$@?$^

%.o?:?%.cpp
????g ?-c?-o?$@?$<

clean:
????rm?-f?*.o?Human?
上述代碼就不再這里贅述了,跟之前教程中的?Makefile基本是一樣的,有了Makefile之后,編譯代碼只需要使用?make命令就行了,編譯結(jié)果如下所示:

image-20210222105051169
上述代碼中,如果我們想要增添功能,比如說ChineseEnglishman都有名字,那么就可以增添設(shè)置名字和獲取名字這兩種方法,首先是?Chinese的代碼,代碼如下:

#ifndef?_CHINESE_H
#define?_CHINESE_H

#include?
#include?
#include?

using?namespace?std;

class?Chinese{
private:
????char?*name;
public:
????void?setName(char?*name);
????char?*getName(void);
????void?eating(void);
????void?wearing(void);
????void?driving(void);
????~Chinese();
};

#endif
然后是.cpp中的代碼:

#include?"Chinese.h"

void?Chinese::setName(char?*name)?
{
????this->name?=?name;
}

char?*Chinese::getName(void)?
{
????return?this->name;
}

/*其他成員函數(shù)實(shí)現(xiàn)同上,這里省略*/
寫完了?Chinese的代碼,然后是Englishman中的代碼,首先是Englishman.h中的代碼:

#ifndef?_ENGLISHMAN_H
#define?_ENGLISHMAN_H

#include?
#include?
#include?

using?namespace?std;

class?Englishman?{
private:
????char?*name;
public:
????void?setName(char?*name);
????char?*getName(void);
????void?eating(void);
????void?wearing(void);
????void?driving(void);
????~Englishman();
};

#endif
緊接著,是.cpp中的代碼:

#include?"Englishman.h"

void?Englishman::setName(char?*name)?
{
????this->name?=?name;
}

char?*Englishman::getName(void)?
{
????return?this->name;
}
以這樣的方式增添功能,確實(shí)是可行的,但是我們假設(shè)一下,如果類很多,除了中國人和英國人還有很多個(gè)國家的人,如果這些類都要增加相同的功能,這個(gè)工作量就比較大了,那要如何解決這個(gè)問題呢?這個(gè)時(shí)候,我們就可以引入一個(gè)新類Human,然后,將每個(gè)類相同的部分寫在這個(gè)類里面,其他類,諸如EnglisnmanChinese就可以從Human類中繼承而來,那這個(gè)時(shí)候,增添的操作,就只需要在?Human類中增加就好了,不需要改動(dòng)ChineseEnglishman,工作量就小了很多。我們來看?Human類的代碼實(shí)現(xiàn),首先是.h代碼的實(shí)現(xiàn):

#ifndef?_HUMAN_H
#define?_HUMAN_H

#include?
#include?
#include?

using?namespace?std;

class?Human?{
private:
????char?*name;

public:
????void?setName(char?*name);
????char?*getName(void);????
};

#endif
然后是.cpp代碼的實(shí)現(xiàn):

#include?"Human.h"

void?Human::setName(char?*name)?
{
????this->name?=?name;
}

char?*Human::getName(void)?
{
????return?this->name;
}
有了?Human類之后,我們就可以來實(shí)現(xiàn)我們所說的?EnglishmanChinese類了,代碼如下所示:

#ifndef?_ENGLISHMAN_H
#define?_ENGLISHMAN_H

#include?
#include?
#include?

#include?"Human.h"

using?namespace?std;

class?Englishman?:?public?Human?
{
public:
????void?eating(void);
????void?wearing(void);
????void?driving(void);
????~Englishman();
};

#endif
然后是Chinese的代碼:

#ifndef?_CHINESE_H
#define?_CHINESE_H

#include?
#include?
#include?

#include?"Human.h"

using?namespace?std;

class?Chinese?:?public?Human
{
public:
????void?eating(void);
????void?wearing(void);
????void?driving(void);
????~Chinese();
};

#endif
可以看到?EnglishmanChinese都是繼承自Human類,這個(gè)時(shí)候,就不需要再自己實(shí)現(xiàn)setNamegetName了。

我們繼續(xù)來完善我們的代碼,先從主函數(shù)說起,主函數(shù)代碼如下所示:

void?test_eating(Human?*h)
{
????h->eating();
}

int?main(int?argc,?char?**argv)
{
????Englishman?e;
????Chinese?c;

????Human?*?h[2]?=?{
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉