您好,登錄后才能下訂單哦!
《繼承》
一丶定義:
在C++語言中,一個派生類可以從一個基類派生,也可以從多個基類派生。從一個基類派生的繼承稱為單繼承;從多個基類進程派生的稱為多繼承。
類的繼承,就是新的類從已有類那里得到已有的屬性,從已有類產(chǎn)生新類的過程就是類的派生。
原有的類稱為基類或者父類,產(chǎn)生的類稱為派生類或者子類。
二丶繼承的方式:
1.公有繼承(public)
當類的繼承方式為公有繼承時,基類的公有成員和保護成員的訪問屬性在派生類中不變,而基類的私有成員不可直接訪問。
2.保護繼承(protect)
保護繼承忠,基類的公有成員和保護成員都以保護成員的身份出現(xiàn)在派生類中,而基類的私有成員不可直接訪問。
3.私有繼承(private)
當類的繼承方式為私有繼承時,基類中的公有成員和保護成員都以私有成員身份出現(xiàn)在派生類中,而基類的私有成員在派生類中不可直接訪問。
三丶類型兼容性規(guī)則
1.派生類的對象可以隱含的轉(zhuǎn)換為基類對象
class B{.....} class D:public B{} B b1,*pb1; D d1; b1=d1;
2.派生類的對象可以初始化基類的引用
class B{.....} class D:public B{} B b1,*pb1; D d1; B &rb=d1;
3.派生類的指針可以隱含轉(zhuǎn)換為基類的指針
class B{.....} class D:public B{} B b1,*pb1; D d1; pb1=&d1;
四丶派生類的構(gòu)造和析構(gòu)函數(shù)
基類的對象必須調(diào)用基類的構(gòu)造函數(shù)來進行初始化。所以,在派生類中,創(chuàng)建對象時,應(yīng)該先調(diào)用基類構(gòu)造函數(shù),再調(diào)用自身構(gòu)造函數(shù)進行初始化。
五丶多繼承
當某類的部分或全部直接基類是從另一個共同基類派生而來,在這些直接基類中從上一層共同基類繼承來的成員就擁有相同的名稱。在派生類的對象中,這些同名數(shù)據(jù)成員在內(nèi)存中同時擁有多個副本,同一個函數(shù)名會有多個映射??梢允褂米饔糜蚍直娣麃砦ㄒ粯俗R并分別訪問它們,也可以將共同基類設(shè)置為虛基類(virtual)。這時,從不同的路徑繼承過來的同名數(shù)據(jù)成員在內(nèi)存中就只有一個副本,同一個函數(shù)名也只有一個映射。
class 派生類名:virtual 繼承方式 基類名
六丶派生類的內(nèi)存布局
派生類對象的內(nèi)存布局需滿足的要求是,一個基類指針,無論其指向基類對象,還是派生類對象,通過它來訪問一個基類中定義的數(shù)據(jù)成員,都可以用相同的步驟。不同的編譯器可以有不同的實現(xiàn),這點要切記。
單繼承情況:
class Base{。。。}; class Derived:public Base{ 。。}; Base *pba=new Base; Derived *pd=new Derived; Base *pbb=pd;
在Derived類的對象中,Derived從Base繼承來的數(shù)據(jù)成員,全部放在前面,與這些數(shù)據(jù)成員在Base類的對象中放置的順序保持一致,Derived類新增的數(shù)據(jù)成員全部放放在后面。
所以在pd賦pbb的過程中,指針不需要改變。pba和pbb這兩個Base類型的指針,雖然指向的對象具有不同的類型,但任何一個Base數(shù)據(jù)成員到該對象首地址都具有相同的偏移量,因此,使用Base指針pba和pbb訪問Base類中定義的數(shù)據(jù)成員時,可以采用相同的方式,而無須考慮具體的對象類型。
多繼承情況:
class Base1{。。。}; class Base2{。。。。}; class Derived:public Base1,public Base2{ 。。}; Base1 *pbla=new Base1; Base2 *pb2a=new Base2; Derived *pd=new Derived; Base1 *pb1b=pd; Base2 *pb2b=pd;
將pd賦值給pd1b指針時,與單繼承時的情形相似,只需要把地址復(fù)制一遍即可。但將pd賦值給pb2b指針時,不能簡單執(zhí)行地址復(fù)制操作,而應(yīng)當在源地址的基礎(chǔ)上加一個偏移量,使pb2b指針指向Derived對象中Base2類的成員的首地址。這樣對于同為Base2類型指針的pb2a和pb2b來說,它們都指向Base2中定義的丶以相同方式分布的數(shù)據(jù)成員。
虛擬繼承的情況:
class Base0{......}; class Base1:public Base0{......}; class Base2:public Base0{.......}; class Derived:public Base1,public Base2{.......}
Base1類型指針和Base2類型指針都可以指向Derived對象,而且通過這兩類指針都可以訪問Base0類中定義的數(shù)據(jù)成員,但這些數(shù)據(jù)成員在Derived對象中只有一份。一種比較理解的布局是:
在Base1類型對象和Base2類型對象中都增加一個隱含的指針,這個指針指向Base0中定義的數(shù)據(jù)成員的首地址。Derived類同時繼承了Base1和Base2類,因此要把兩個類中的隱含指針分別繼承下來,但由于Derived類中的Base0類數(shù)據(jù)成員只有一份,因此Derived類型對象中的這兩個隱含指針指向相同的地址。通過Base1類型指針和Base2類型指針訪問Base0類的數(shù)據(jù)成員時,都可以通過指針來間接訪問。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。