初识C++之继承
1、何為繼承
C++中所謂繼承,就是在一個(gè)已存在類的基礎(chǔ)上創(chuàng)建一個(gè)新的類,新類獲得已存在類的部分特性(為什么是部分特性,后面會(huì)講到)。已存在類被稱為基類(Base Class)或父類(Father Class),新建類被稱為派生類(Derived Class)或子類(Son Class)。
繼承的聲明形式:
class 派生類名:[繼承方式] 基類列表
{
派生類增加的特性;
}
2、分類
繼承在C++中有單繼承與多繼承的分類。
單繼承:派生類有且只有一個(gè)基類
多繼承:派生類兩個(gè)或兩個(gè)以上的基類
文字描述不過癮,給出聲明方法、模型及實(shí)例:
①簡(jiǎn)單的單繼承聲明方法、模型及實(shí)例:
class 派生類名:[繼承方式] 基類名
{
派生類增加的特性;
}
②簡(jiǎn)單的多繼承聲明方法、模型及實(shí)例:
class 派生類名:[繼承方式] 基類列表
{
派生類增加的特性;
}
3、繼承方式
先來回憶一下繼承的聲明形式:
class 派生類名:[繼承方式] 基類列表
{
派生類增加的特性;
}
其中,繼承方式分為共有(public)、私有(private)、保護(hù)(protected)之分,不同的繼承方式會(huì)產(chǎn)生不同的繼承效果(class默認(rèn)繼承方式是私有,struct默認(rèn)繼承方式是公有,但最好還是顯示給出繼承方式,這樣會(huì)使程序更加清晰)。
繼承方式的區(qū)別:
public:基類的非私有成員在派生類中的訪問屬性不變,基類的私有屬性在派生類中存在但不可見。
protected:基類的非私有成員都稱為派生類中的保護(hù)成員,基類的私有屬性在派生類中存在但不可見。
private:基類的非私有成員都稱為派生類中的私有成員,基類的私有屬性在派生類中存在但不可見。
以上就是為什么說只是基類的部分特性在派生類中可見。
輸出結(jié)果:
對(duì)以上輸出結(jié)果分析:
①為什么ShowBase會(huì)被調(diào)用兩次
ShowBase函數(shù)被調(diào)用了兩次,是因?yàn)樵贒erived類中,繼承有ShowBase函數(shù),因?yàn)樵摵瘮?shù)在Base類中的屬性是public,而且Derived類是以public方式繼承自Base類的,所以該函數(shù)在Derived類中的屬性仍為public,那么它就可以在類外被調(diào)用。
②為什么兩個(gè)類的大小不同
從輸出結(jié)果中很明顯的看到,Base類的大小為12,Derived類的大小為2。Base類的大小為12很好理解,因?yàn)樗锩嬷挥腥齻€(gè)成員變量,且都為int類型,但為什么Derived是24呢,這就要牽扯到了繼承方式特性,不管繼承方式是什么,基類的成員變量的訪問限定符是什么,基類的成員變量在派生類中都是存在的,只是有可見與不可見之分。
當(dāng)我把繼承方式修改為protected和private時(shí),程序編譯出錯(cuò):
這就印證了我們上述的繼承方式的特性,因?yàn)閜rotected繼承方式會(huì)把Base類中public訪問限定符的BaseShow函數(shù)在Derived類中降級(jí)為protected訪問限定符,同樣,private繼承方式會(huì)把Base類中public訪問限定符的BaseShow函數(shù)在Derived類中降級(jí)為private訪問限定符,而protected訪問限定符和private訪問限定符修飾的內(nèi)容在類外是不可見的,強(qiáng)行調(diào)用肯定會(huì)報(bào)錯(cuò),所以這兒會(huì)出現(xiàn)錯(cuò)誤。
繼承方式的特性:
①基類的private成員在派生類中是不能被訪問的,如果基類成員不想在類外直接被訪問,但需要在派生類中能訪問,就定義為protected。可以看出保護(hù)成員限定符是因繼承才出現(xiàn)的。
②不管是哪種繼承方式,在派生類內(nèi)部都可以訪問基類的公有成員和保護(hù)成員,基類的私有成員存在但是在子類中不可見(不能訪問)。
③使用關(guān)鍵字class時(shí)默認(rèn)的繼承方式是private,使用struct時(shí)默認(rèn)的繼承方式是public,不過最好顯示的寫出繼承方式。
4、繼承關(guān)系中構(gòu)造函數(shù)和析構(gòu)函數(shù)的調(diào)用
先給出一個(gè)例子來剖析:
可以看到在派生類創(chuàng)建對(duì)象時(shí),是先調(diào)用基類的構(gòu)造函數(shù),然后在代用自己的構(gòu)造函數(shù),對(duì)于析構(gòu)函數(shù)就很好解釋了,可以理解為棧的特性,先進(jìn)后出。
5、繼承關(guān)系的作用域
在C++的繼承體系中,基類和派生類是屬于兩個(gè)不同作用域。當(dāng)基類和派生類中有同名成員時(shí),派生類成員將屏蔽基類對(duì)成員的直接訪問(在派生類成員函數(shù)中,可以使用 基類名::基類成員來訪問基類的同名成員),這就是所謂的同名隱藏,在派生類中的同名成員稱為對(duì)基類同名成員的重定義。當(dāng)然,實(shí)際中在繼承體系里面最好不要定義同名的成員。
注意:因?yàn)榛惡团缮愂菍儆趦蓚€(gè)不同作用域,所以兩個(gè)類中的同名函數(shù)不會(huì)構(gòu)成函數(shù)重載。
根據(jù)上面例子的輸出就可以看出來。
6、基類對(duì)象與派生類對(duì)象的賦值關(guān)系
①子類對(duì)象可以賦值給父類對(duì)象
#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> using namespace std;class Base { public:Base(int bpub = 5, int bpri = 10, int bpro = 15): pub(bpub), pri(bpri), pro(bpro){}~Base(){}void Display(){cout << "Base::Display" << endl;cout << "pub = " << pub << endl;cout << "pri = " << pri << endl;cout << "pro = " << pro << endl;}public:int pub; private:int pri; protected:int pro; };class Derived: public Base { public:Derived(int _dpub = 10, int _dpri = 20, int _dpro = 30): _pub(_dpub), _pri(_dpri), _pro(_dpro){}~Derived(){}void Display(){cout << "Derived::Display" << endl;cout << "_pub = " << _pub << endl;cout << "_pri = " << _pri << endl;cout << "_pro = " << _pro << endl;}public:int _pub; private:int _pri; protected:int _pro; };int main() {Base b(1, 2, 3);Derived d(4, 5, 6);b = d;b.Display();d.Display();return 0; }輸出結(jié)果:
程序可以正常輸出,但有些人可能會(huì)奇怪,為什么b里面存的是5、10、15,而不是4、5、6,其實(shí)原因很簡(jiǎn)單:
②父類對(duì)象不能賦值給子類對(duì)象
當(dāng)我把上例中的“b = d;”換成“d = b;”時(shí),編譯器會(huì)報(bào)錯(cuò):
還是像剛才那樣分析:
③父類的指針/引用可以指向子類對(duì)象,但是無法使用不存在于基類只存在于派生類的元素。
輸出結(jié)果:
上分析圖:
④子類的指針/引用不能指向父類對(duì)象(可以通過強(qiáng)制類型轉(zhuǎn)換完成)
我把上例中的
換成
int main() {Base b(4, 5, 6);Derived *d = &b;d->Display();return 0; }程序會(huì)報(bào)錯(cuò):
繼續(xù)上圖分析:
7、友元與繼承
友元關(guān)系不能繼承,也就是說基類友元不能訪問子類私有和保護(hù)成員。
8、繼承與靜態(tài)成員
基類定義了static成員,則整個(gè)繼承體系里面只有一個(gè)這樣的成員。無論派生出多少個(gè)子類,都只有一個(gè)static成員實(shí)例。
可以看到兩次輸出都是10。
總結(jié)
- 上一篇: 东莞 小学计算机编程大赛,关于举办第二十
- 下一篇: [Deepin - Pycharm] P