最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++?繼承的范例講解

 更新時(shí)間:2022年06月06日 08:39:20   作者:林慢慢腦瓜子嗡嗡的  
繼承是C++面向?qū)ο缶幊讨械囊婚T。繼承是子類繼承父類的特征和行為,或者是繼承父類得方法,使的子類具有父類得的特性和行為。重寫是子類對(duì)父類的允許訪問的方法實(shí)行的過程進(jìn)行重新編寫,返回值和形參都不能改變。就是對(duì)原本的父類進(jìn)行重新編寫,但是外部接口不能被重寫

1.繼承的概念

繼承,是面向?qū)ο蟮娜筇匦灾?。繼承可以理解成是類級(jí)別的一個(gè)復(fù)用,它允許我們?cè)谠蓄惖幕A(chǔ)上進(jìn)行擴(kuò)展,增加新的功能。

當(dāng)創(chuàng)建一個(gè)類時(shí),我們可以繼承一個(gè)已有類的成員和方法,并且在原有的基礎(chǔ)上進(jìn)行提升,這個(gè)被繼承的類叫做基類,而這個(gè)繼承后新建的類叫做派生類。

用法如下:

class [派生類名] : [繼承類型] [基類名]

例如:

class Person
{
public:
	string _name;
	int _age;
};
class Student : public Person
{
protected:
	string _stuNum;
};

這里的派生類Student就復(fù)用了Person的方法和成員,并在此基礎(chǔ)上擴(kuò)展補(bǔ)充。

2.繼承方式

繼承的方式和類的訪問限定符一樣,分為public(公有繼承),private(私有繼承), protected(保護(hù)繼承)三種。

不同的繼承方式,在派生類中繼承下來(lái)的基類成員的訪問權(quán)限也不一樣。

基類的其他成員在子類的訪問方式 = Min(成員在基類的訪問限定符,繼承方式)

備注:

1.在實(shí)際運(yùn)用中一般使用都是public繼承,幾乎很少使用protetced/private繼承,也不提倡使用protetced/private繼承,因?yàn)閜rotetced/private繼承下來(lái)的成員都只能 在派生類的類里面使用,實(shí)際中擴(kuò)展維護(hù)性不強(qiáng)。

2.使用關(guān)鍵字class時(shí)默認(rèn)的繼承方式是private,使用struct時(shí)默認(rèn)的繼承方式是public,不過最好顯示的寫出繼承方式。

3.基類與派生類的賦值轉(zhuǎn)換

派生類可以賦值給基類的對(duì)象、指針或者引用,這樣的賦值也叫做對(duì)象切割。

例如上面的Person類和Student類

這種賦值只能是派生類賦給基類(但需要割掉多出來(lái)的成員例如_ stuID),而基類對(duì)象不能賦給派生類。

基類的指針可以強(qiáng)制類型轉(zhuǎn)換賦值給派生類的指針, 如:

int main()
{
	Person p1;
	Student s1;
	Person* hPtr1 = &s1;//指向派生類對(duì)象
	Person* hPtr2 = &p1;//指向基類對(duì)象
	Student* pPtr = (Student*)hPtr1;//沒問題
	Student* pPtr = (Student*)hPtr2;//有時(shí)候沒有問題,但是會(huì)存在越界風(fēng)險(xiǎn)
	return 0;
}

小結(jié):

1.派生類可以賦值給基類的對(duì)象、指針或者引用

2.基類對(duì)象不能賦值給派生類對(duì)象

3.基類的指針可以通過強(qiáng)制類型轉(zhuǎn)換賦值給派生類的指針。**??但是必須是基類的指針是指向派生類對(duì)象時(shí)才是安全的,否則會(huì)存在越界的風(fēng)險(xiǎn)。**這里基類如果是多態(tài)類型,可以使用RTT的dynamic_cast來(lái)進(jìn)行識(shí)別后進(jìn)行安全轉(zhuǎn)換。

4.作用域與隱藏

??隱藏:隱藏,也叫做重定義,當(dāng)基類和派生類中出現(xiàn)重名的成員時(shí),派生類就會(huì)將基類的同名成員給隱藏起來(lái),然后使用自己的。(但是隱藏并不意味著就無(wú)法訪問,可以通過指明基類作用域來(lái)顯式訪問隱藏成員。)

class Person
{
public:
	void f(int age)
	{
		cout << "姓名" << _name << endl;
		cout << "年齡" << _age << endl;
	}
protected:
	string _name;
	int _age;
};
class Student : public Person
{
public:
	void f()
	{
		Person::f(32);//需顯式調(diào)用f函數(shù)
		cout << "學(xué)號(hào)" << _stuNum << endl;
	}
private:
	string _stuNum;
};

例如這里的f( )就構(gòu)成了隱藏

同時(shí),這里還有個(gè)需要注意的問題,在基類與派生類中,同名的方法并不能構(gòu)成重載,因?yàn)樘幱诓煌淖饔糜蛑?。而只要滿足方法名相同,就會(huì)構(gòu)成隱藏。

5.派生類的默認(rèn)成員函數(shù)

在每一個(gè)類中,都會(huì)有6個(gè)默認(rèn)的成員函數(shù),這些函數(shù)即使我們自己不去實(shí)現(xiàn),編譯器也會(huì)幫我們實(shí)現(xiàn)。

??這里有兩點(diǎn)需要注意(筆試題常考):

1.構(gòu)造函數(shù),拷貝構(gòu)造,operator=三種情況,都要調(diào)用父類對(duì)應(yīng)的構(gòu)造函數(shù)/拷貝構(gòu)造/operator=進(jìn)行對(duì)父類的成員變量的初始化,并且倘若父類沒有默認(rèn)的構(gòu)造函數(shù)的時(shí)候(比如父類寫了帶參的構(gòu)造函數(shù)),我們就要顯式調(diào)用(Person(參數(shù)…),Person::operator=(參數(shù)…))

??構(gòu)造函數(shù)顯示調(diào)用

派生類的構(gòu)造函數(shù)必須調(diào)用基類的構(gòu)造函數(shù)初始化基類的那一部分成員。如果基類沒有默認(rèn)的構(gòu)造函 數(shù),則必須在派生類構(gòu)造函數(shù)的初始化列表階段顯示調(diào)用。

Student()
    	:People()
	{
		cout << "Student()" << endl;
	}

??拷貝構(gòu)造顯示調(diào)用

建議拷貝構(gòu)造都用顯示調(diào)用,不然免不了出現(xiàn)子類拷貝構(gòu)造當(dāng)中調(diào)用了父類的構(gòu)造函數(shù)的情況(因?yàn)榭截悩?gòu)造也是構(gòu)造,在初始化列表處,對(duì)于子類而言,父類相當(dāng)于一個(gè)自定義類型對(duì)象,子類會(huì)調(diào)用父類的構(gòu)造函數(shù)對(duì)父類的資源進(jìn)行初始化。)

Student(const Student& s)
		:People(s)
	{
		cout << "Student(const Student& s)" << endl;
	}

??派生類的operator=必須要調(diào)用基類的operator=完成基類的復(fù)制。

Student& operator=(const Student& s)
	{
		cout << "Student& operator = (const Student& s)" << endl;
		if (this != &s)
		{
			Person:: operator=(s);
		}
	}

??析構(gòu)函數(shù)

由于編譯器會(huì)將析構(gòu)函數(shù)的名字處理成destructor,因此派生類和基類的析構(gòu)函數(shù)會(huì)構(gòu)成隱藏關(guān)系,故若要派生類要調(diào)用基類的析構(gòu)函數(shù),那么需要顯式調(diào)用,但是編譯器會(huì)默認(rèn)在派生類的析構(gòu)函數(shù)調(diào)用結(jié)束后調(diào)用基類的析構(gòu)函數(shù),這樣就析構(gòu)兩次了。

	~Person()
	{
		cout << "~Person()" << endl;
	}
	~Student()
	{
		Person:: ~Person();
		cout << "~Student()" << endl;
	}

在派生類中,基類的析構(gòu)函數(shù)會(huì)被隱藏,雖然它們這里的名字不同,但是為了實(shí)現(xiàn)多態(tài), 它們都會(huì)被編譯器重命名為destructor。在調(diào)用子類的構(gòu)造函數(shù)時(shí),我們是先調(diào)用父類的構(gòu)造函數(shù),后對(duì)子類的成員進(jìn)行構(gòu)造。由先構(gòu)造后析構(gòu)的順序,所以我們是在析構(gòu)函數(shù)當(dāng)中析構(gòu)子類的資源,析構(gòu)函數(shù)調(diào)用完后編譯器自動(dòng)幫我們調(diào)用父類的析構(gòu)函數(shù)。

6.友元與靜態(tài)成員

??1.友元

友元關(guān)系是不會(huì)繼承的,如果子類要使用父類的友元,則子類自己也要將其定義為友元。

??2.靜態(tài)成員

基類定義了static靜態(tài)成員,無(wú)論繼承了多少次,派生了多少子類,靜態(tài)成員在這整個(gè)繼承體系中有且只有一個(gè)。靜態(tài)成員不再單獨(dú)屬于某一個(gè)類亦或者是某一個(gè)對(duì)象,而是屬于這一整個(gè)繼承體系。

7.菱形繼承與虛繼承

首先簡(jiǎn)單介紹下單繼承、多繼承的概念

單繼承:一個(gè)子類只有一個(gè)直接父類時(shí)稱這個(gè)繼承關(guān)系為單繼承

多繼承:一個(gè)子類有兩個(gè)或以上直接父類時(shí)稱這個(gè)繼承關(guān)系為多繼承

菱形繼承:菱形繼承是多繼承的一種特殊情況,下面簡(jiǎn)單舉例介紹下菱形繼承及其帶來(lái)的二義性問題:

class Human
{
public:
	int _age;
};
class Student : public Human
{
public:
	int _stuNum;
};
class Teacher : public Human
{
public:
	int _teaNum;
};
class Assistant : public Teacher, public Student
{
};

哦豁?。?!菱形繼承這個(gè)關(guān)系感受到了吧!??!

??直接講下這個(gè)菱形繼承帶來(lái)的二義性問題:

按照道理來(lái)說(shuō),各個(gè)類的大小應(yīng)該是這樣的。human類4個(gè)字節(jié),teacher和student都是8個(gè)字節(jié),而assistant是12個(gè)字節(jié),但是實(shí)際上assistant卻是16字節(jié)。

??為什么assistant會(huì)有16字節(jié)?

這就是菱形繼承的數(shù)據(jù)冗余和二義性問題的體現(xiàn)。

這里的teacher和student都從human中繼承了相同的成員 _age。但是assistant再?gòu)膖eacher和student繼承時(shí),就分別把這兩個(gè) _age都給繼承了過來(lái),導(dǎo)致這里有了兩個(gè)一樣的成員。

在這樣的情況下,后續(xù)想給 _age賦值,也會(huì)被編譯器提示指示不明確,報(bào)錯(cuò)。

??菱形繼承的二義性是很致命的問題,如何解決呢?

虛繼承,在腰部的類繼承時(shí)添加virtual關(guān)鍵字。

class Student : virtual public Human
{
public:
	int _stuNum;
};
class Teacher : virtual public Human
{
public:
	int _teaNum;
};
class Assistant : public Teacher, public Student
{
};

這次,二義性問題解決了,teacher和student都是12個(gè)字節(jié),而assistant是20個(gè)字節(jié)。

想知道為什么?點(diǎn)這里:從內(nèi)存角度看待虛繼承

??簡(jiǎn)單小結(jié)一下

1.可以看到?jīng)]有虛繼承的情況下,Assitant中的成員連續(xù)排列出現(xiàn)了Teacher和Student中的_age是兩個(gè)不同的值,但實(shí)際上一個(gè)人不會(huì)有兩個(gè)年齡,所以這就出現(xiàn)了數(shù)據(jù)冗余。

2.這里多出來(lái)的8個(gè)字節(jié),其實(shí)是兩個(gè)虛基表指針。因?yàn)檫@里Human中的 _age是 teacher和 student共有的,所以為了能夠方便處理,在內(nèi)存中分布的時(shí)候,就會(huì)把這個(gè)共有成員 _age放到對(duì)象組成的最末尾的位置。然后通過了Teacher和Student的兩個(gè)指針,指向的一張表。這兩個(gè)指針叫虛基表指針,這兩個(gè)表叫虛基表。虛基表中存的偏移量。通過偏移量可以找到下面的Human。由此可見,使用了虛擬繼承后,就可以解決菱形繼承導(dǎo)致的問題。

??為什么Teacher、Student需要去找屬于自己的 _age?

基類與派生類的賦值轉(zhuǎn)換時(shí),需要進(jìn)行切片。

int main()
{
	Assistant a;
	Teacher t = a; 
	Student s = a;
	return 0;
}

當(dāng)把對(duì)象a賦值給t和s的時(shí)候,因?yàn)樗麄兓ハ鄾]有對(duì)方的 _stuNum和 _teaNum,所以他們需要進(jìn)行對(duì)象的切割,但是又因?yàn)?_age存放在對(duì)象的最尾部,所以只有知道了自己的偏移量,才能夠成功的在切割了沒有的元素時(shí),還能找到自己的 _age。

8.繼承和組合

??繼承是一種復(fù)用的方式,但不是唯一方式!

1.public繼承是一種is-a的關(guān)系,就是基類是一個(gè)大類,而派生類則是這個(gè)大類中細(xì)分出來(lái)的一個(gè)子類,但是他們本質(zhì)上其實(shí)是一種東西。

2.組合是一種has-a的關(guān)系,就是一種包含關(guān)系,比如對(duì)象a是對(duì)象b的成員,那么他們的關(guān)系就是對(duì)象b的組成中包含了對(duì)象a,對(duì)象a是對(duì)象b中的一部分,對(duì)象b包含對(duì)象a。

3.繼承方式的復(fù)用常稱之為白箱復(fù)用,在繼承方式中,基類的內(nèi)部細(xì)節(jié)對(duì)子類可見,這一定程度上破壞了基類的封裝,伴隨著基類的改變,對(duì)派生類的改變很大。并且兩者依賴關(guān)系強(qiáng),耦合度大。

4.對(duì)象組合式繼承之外的復(fù)用選擇,對(duì)象組合要求被組合對(duì)象提供良好的接口定義。這種復(fù)用稱之為黑箱復(fù)用,對(duì)象的內(nèi)部實(shí)現(xiàn)細(xì)節(jié)是不可見的。耦合度低。

實(shí)際工程中能用繼承和組合就用組合,組合的耦合度低,代碼的維護(hù)性好,但是繼承在有些關(guān)系就適合用繼承就用繼承,并且要實(shí)現(xiàn)多態(tài)就一定要用繼承。

到此這篇關(guān)于C++ 繼承的范例講解的文章就介紹到這了,更多相關(guān)C++ 繼承內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言之飛機(jī)大戰(zhàn)游戲

    C語(yǔ)言之飛機(jī)大戰(zhàn)游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言之飛機(jī)大戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • C語(yǔ)言實(shí)現(xiàn)旅游資訊管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)旅游資訊管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)旅游資訊管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語(yǔ)言文件操作大全

    C語(yǔ)言文件操作大全

    這篇文章主要介紹了C語(yǔ)言文件操作大全的相關(guān)資料,需要的朋友可以參考下
    2018-03-03
  • C語(yǔ)言結(jié)構(gòu)體版學(xué)生成績(jī)管理系統(tǒng)

    C語(yǔ)言結(jié)構(gòu)體版學(xué)生成績(jī)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言結(jié)構(gòu)體版的學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C++詳細(xì)講解圖的遍歷

    C++詳細(xì)講解圖的遍歷

    圖的遍歷是指,從給定圖中任意指定的頂點(diǎn)(稱為初始點(diǎn))出發(fā),按照某種搜索方法沿著圖的邊訪問圖中的所有頂點(diǎn),使每個(gè)頂點(diǎn)僅被訪問一次,這個(gè)過程稱為圖的遍歷
    2022-05-05
  • C++?ncnn模型驗(yàn)證精度實(shí)現(xiàn)代碼

    C++?ncnn模型驗(yàn)證精度實(shí)現(xiàn)代碼

    這篇文章主要介紹了C++?ncnn模型驗(yàn)證精度實(shí)現(xiàn)過程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-02-02
  • 淺談C++11中=delete的巧妙用法

    淺談C++11中=delete的巧妙用法

    本文主要介紹了C++11中=delete的巧妙用法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C++中sort函數(shù)的基礎(chǔ)入門使用教程

    C++中sort函數(shù)的基礎(chǔ)入門使用教程

    這篇文章主要給大家介紹了關(guān)于C++中sort函數(shù)的基礎(chǔ)入門使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧
    2018-12-12
  • C語(yǔ)言算法練習(xí)之抓交通肇事犯

    C語(yǔ)言算法練習(xí)之抓交通肇事犯

    這篇文章主要該大家分享C語(yǔ)言算法抓交通肇事犯的練習(xí),文章主要通過描述抓交通肇事犯得問題然后確定程序框架將結(jié)果運(yùn)算出來(lái),下面來(lái)看詳細(xì)內(nèi)容吧,需要的朋友可以參考一下
    2022-03-03
  • C語(yǔ)言實(shí)現(xiàn)在windows服務(wù)中新建進(jìn)程的方法

    C語(yǔ)言實(shí)現(xiàn)在windows服務(wù)中新建進(jìn)程的方法

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)在windows服務(wù)中新建進(jìn)程的方法,涉及C語(yǔ)言進(jìn)程操作的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06

最新評(píng)論

新竹市| 宝丰县| 湄潭县| 呼图壁县| 加查县| 根河市| 梁平县| 昌黎县| 余干县| 岚皋县| 万年县| 太仆寺旗| 民丰县| 武鸣县| 永安市| 长垣县| 邯郸县| 缙云县| 乐平市| 延寿县| 洪雅县| 施甸县| 邮箱| 通道| 高尔夫| 门头沟区| 娄底市| 奉贤区| 常山县| 郸城县| 塘沽区| 龙泉市| 丰都县| 保康县| 凯里市| 河北省| 淳化县| 桂东县| 衡南县| 临武县| 温泉县|