一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

c++ 類的繼承與派生

 piaoyedu 2013-08-26

一、基本概念

1、類的繼承,是新的類從已有類那里得到已有的特性?;驈囊延蓄惍a(chǎn)生新類的過(guò)程就是類的派生。原有的類稱為基類或父類,產(chǎn)生的新類稱為派生類或子類。
2、派生類的聲明:
class 派生類名:繼承方式 基類名1, 繼承方式 基類名2,...,繼承方式 基類名n
{
    派生類成員聲明;
};
3、一個(gè)派生類可以同時(shí)有多個(gè)基類,這種情況稱為多重繼承,派生類只有一個(gè)基類,稱為單繼承。直接派生,間接派生。
4、繼承方式規(guī)定了如何訪問(wèn)基類繼承的成員。繼承方式有public, private, protected。如果不顯示給出繼承方式,默認(rèn)為private繼承。繼承方式指定了派生類成員以及類外對(duì)象對(duì)于從基類繼承來(lái)的成員的訪問(wèn)權(quán)限。
5、派生類繼承基類中除構(gòu)造和析構(gòu)函數(shù)以外的所有成員。
6、派生類生成:
   吸收基類成員(除構(gòu)造析構(gòu)函數(shù)以外的所有成員);
   改造基類成員(根據(jù)繼承方式調(diào)整基類成員的訪問(wèn),函數(shù)在子類中的覆蓋,以及虛函數(shù)在子類中的覆蓋);
   添加新的成員;
7、公有繼承
當(dāng)類的繼承方式為公有繼承時(shí),基類的公有和保護(hù)成員的訪問(wèn)屬性在派生類中不變,而基類的私有成員不可訪問(wèn)。即基類的公有成員和保護(hù)成員被繼承到派生類中仍作為派生類的公有成員和保護(hù)成員。派生類的其他成員可以直接訪問(wèn)它們。無(wú)論派生類的成員還是派生類的對(duì)象都無(wú)法訪問(wèn)基類的私有成員。
8、私有繼承
當(dāng)類的繼承方式為私有繼承時(shí),基類中的公有成員和保護(hù)成員都以私有成員身份出現(xiàn)在派生類中,而基類的私有成員在派生類中不可訪問(wèn)?;惖墓谐蓡T和保護(hù)成員被繼承后作為派生類的私有成員,派生類的其他成員可以直接訪問(wèn)它們,但是在類外部通過(guò)派生類的對(duì)象無(wú)法訪問(wèn)。無(wú)論是派生類的成員還是通過(guò)派生類的對(duì)象,都無(wú)法訪問(wèn)從基類繼承的私有成員。通過(guò)多次私有繼承后,對(duì)于基類的成員都會(huì)成為不可訪問(wèn)。因此私有繼承比較少用。
9、保護(hù)繼承
保護(hù)繼承中,基類的公有成員和私有成員都以保護(hù)成員的身份出現(xiàn)在派生類中,而基類的私有成員不可訪問(wèn)。派生類的其他成員可以直接訪問(wèn)從基類繼承來(lái)的公有和保護(hù)成員,但是類外部通過(guò)派生類的對(duì)象無(wú)法訪問(wèn)它們,無(wú)論派生類的成員還是派生類的對(duì)象,都無(wú)法訪問(wèn)基類的私有成員。
二、派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)
1、派生類中由基類繼承而來(lái)的成員的初始化工作還是由基類的構(gòu)造函數(shù)完成,然后派生類中新增的成員在派生類的構(gòu)造函數(shù)中初始化。
2、派生類構(gòu)造函數(shù)的語(yǔ)法:
派生類名::派生類名(參數(shù)總表):基類名1(參數(shù)表1),基類名(參數(shù)名2)....基類名n(參數(shù)名n),內(nèi)嵌子對(duì)象1(參數(shù)表1),內(nèi)嵌子對(duì)象2(參數(shù)表2)....內(nèi)嵌子對(duì)象n(參數(shù)表n)
{
    派生類新增成員的初始化語(yǔ)句;
}
注:構(gòu)造函數(shù)的初始化順序并不以上面的順序進(jìn)行,而是根據(jù)聲明的順序初始化。
3、如果基類中沒(méi)有不帶參數(shù)的構(gòu)造函數(shù),那么在派生類的構(gòu)造函數(shù)中必須調(diào)用基類構(gòu)造函數(shù),以初始化基類成員。
4、派生類構(gòu)造函數(shù)執(zhí)行的次序:
   調(diào)用基類構(gòu)造函數(shù),調(diào)用順序按照它們被繼承時(shí)聲明的順序(從左到右);
   調(diào)用內(nèi)嵌成員對(duì)象的構(gòu)造函數(shù),調(diào)用順序按照它們?cè)陬愔新暶鞯捻樞颍?/div>
   派生類的構(gòu)造函數(shù)體中的內(nèi)容。
例子:
復(fù)制代碼
#include <iostream> #include <time.h> using namespace std; class B1 { public: B1(int i) { cout<<"constructing B1 "<<i<<endl; } }; class B2 { public: B2(int j) { cout<<"constructing B2 "<<j<<endl; } }; class B3 { public: B3() { cout<<"constructing B3"<<endl; } }; class C: public B2, public B1, public B3 { public: C(int a, int b, int c, int d):B1(a), memberB2(d), memberB1(c),B2(b) { } private: B1 memberB1; B2 memberB2; B3 memberB3; }; int main() { C obj(1,2,3,4); return 0; }
復(fù)制代碼

 

輸出結(jié)果為:
constructing B2 2
constructing B1 1
constructing B3
constructing B1 3
constructing B2 4
constructing B3
5、析構(gòu)函數(shù)
派生類的析構(gòu)函數(shù)的功能是在該對(duì)象消亡之前進(jìn)行一些必要的清理工作,析構(gòu)函數(shù)沒(méi)有類型,也沒(méi)有參數(shù)。析構(gòu)函數(shù)的執(zhí)行順序與構(gòu)造函數(shù)相反。
例子:
復(fù)制代碼
#include <iostream> #include <time.h> using namespace std; class B1 { public: B1(int i) { cout<<"constructing B1 "<<i<<endl; } ~B1() { cout<<"destructing B1"<<endl; } }; class B2 { public: B2(int j) { cout<<"constructing B2 "<<j<<endl; } ~B2() { cout<<"destructing B2"<<endl; } }; class B3 { public: B3() { cout<<"constructing B3"<<endl; } ~B3() { cout<<"destructing B3"<<endl; } }; class C: public B2, public B1, public B3 { public: C(int a, int b, int c, int d):B1(a), memberB2(d), memberB1(c),B2(b) { } private: B1 memberB1; B2 memberB2; B3 memberB3; }; int main() { C obj(1,2,3,4); return 0; }
復(fù)制代碼

 

輸出結(jié)果為:
constructing B2 2
constructing B1 1
constructing B3
constructing B1 3
constructing B2 4
constructing B3
destructing B3
destructing B2
destructing B1
destructing B3
destructing B1
destructing B2
三、派生類成員的標(biāo)識(shí)和訪問(wèn)
1、派生類成員屬性劃分為四種:
   不可訪問(wèn)的成員;私有成員;保護(hù)成員;公有成員;
2、作用域分辨
形式為:基類名::成員名;基類名::成員名(參數(shù)表);
如果某派生類的多個(gè)基類擁有同名的成員,同時(shí),派生類又新增這樣的同名成員,在這種情況下,派生類成員將覆蓋所有基類的同名成員。這就需要這樣的調(diào)用方式才能調(diào)用基類的同名成員。
例子:多繼承同名 
復(fù)制代碼
#include <iostream> #include <time.h> using namespace std; class B1 { public: int nV; void fun() { cout<<"member of B1 "<<nV<<endl; } }; class B2 { public: int nV; void fun() { cout<<"member of B2 "<<nV<<endl; } }; class D1: public B1, public B2 { public: int nV; void fun() { cout<<"member of D1 "<<nV<<endl; } }; int main() { D1 d1; d1.nV = 1; d1.fun(); d1.B1::nV = 2; d1.B1::fun(); d1.B2::nV = 3; d1.B2::fun(); return 0; }
復(fù)制代碼

 

輸出結(jié)果為:
member of D1 1
member of B1 2
member of B2 3
以上通過(guò)作用域分辨符,解決了訪問(wèn)基類中被屏蔽的同名成員。
3、如果某個(gè)派生類的部分或全部直接基類是從另一個(gè)共同的基類派生而來(lái),在這些直接基類中,從上一級(jí)基類繼承來(lái)的成員就擁有相同的名稱,因此派生類中也就會(huì)產(chǎn)生同名現(xiàn)象,對(duì)這種類型的同名成員也要使用作用域分辨符來(lái)唯一標(biāo)識(shí),而且必須用直接基類進(jìn)行限定。
例子:
復(fù)制代碼
#include <iostream> #include <time.h> using namespace std; class B0 { public: int nV; void fun() { cout<<"member of B0 "<<nV<<endl; } }; class B1:public B0 { public: int nV1; }; class B2:public B0 { public: int nV2; }; class D1:public B1, public B2 { public: int nVd; void fund() { cout<<"member of D1"<<endl; } }; int main() { D1 d1; d1.B1::nV = 2; d1.B1::fun(); d1.B2::nV = 3; d1.B2::fun(); return 0; }
復(fù)制代碼

 

輸出結(jié)果為:
member of B0 2
member of B0 3
在這種情況下,派生類對(duì)象在內(nèi)存中就同時(shí)擁有成員nV及fun的兩份拷貝。但是很多情況下,我們只需要這樣一個(gè)這樣的數(shù)據(jù)拷貝,同一成員的多份拷貝增加了內(nèi)存的開(kāi)銷。可以通過(guò)虛函數(shù)來(lái)解決這個(gè)問(wèn)題。
4、虛基類
為了解決前面提到的多重拷貝的問(wèn)題,可以將共同基類設(shè)置為虛基類,這時(shí)從不同的路徑繼承過(guò)來(lái)的同名數(shù)據(jù)成員在內(nèi)存中就只有一個(gè)拷貝,同一個(gè)函數(shù)也只有一個(gè)映射。
虛基類的聲明是在派生類的聲明過(guò)程,其語(yǔ)法形式為:
class 派生類名::virtual 繼承方式 基類名;
例子:
復(fù)制代碼
#include <iostream> #include <time.h> using namespace std; class B0 { public: int nV; void fun() { cout<<"member of B0 "<<nV<<endl; } }; class B1:virtual public B0 { public: int nV1; }; class B2:virtual public B0 { public: int nV2; }; class D1:public B1, public B2 { public: int nVd; void fund() { cout<<"member of D1"<<endl; } }; int main() { D1 d1; d1.nV = 2; d1.fun(); return 0; }
復(fù)制代碼

 

輸出結(jié)果為:
member of B0 2
5、虛基類及其派生類的構(gòu)造函數(shù)
一般而言,派生類只對(duì)其直接基類的構(gòu)造函數(shù)傳遞參數(shù),但是在虛基類中,不管是直接或間接虛基類的所有派生類,都必須在構(gòu)造函數(shù)的成員初始化列表中列出對(duì)虛基類的初始化。
例子:
復(fù)制代碼
#include <iostream> #include <time.h> using namespace std; class B0 { public: B0(int n) { nV = n; } int nV; void fun() { cout<<"member of B0 "<<nV<<endl; } }; class B1:virtual public B0 { public: B1(int a):B0(a) { } int nV1; }; class B2:virtual public B0 { public: B2(int a):B0(a) { } int nV2; }; class D1:public B1, public B2 { public: D1(int a):B0(a), B1(a), B2(a) { } int nVd; void fund() { cout<<"member of D1"<<endl; } }; int main() { D1 d1(1); d1.nV = 2; d1.fun(); return 0; }
復(fù)制代碼

 

以上例子看上去B0的構(gòu)造函數(shù)好像被調(diào)用了三次,但是實(shí)際上只有D1類中的D1(int a):B0(a), B1(a), B2(a)
才是真正的調(diào)用了B0構(gòu)造函數(shù)。
四、賦值兼容規(guī)則
1、賦值兼容規(guī)則是指在需要基類對(duì)象的任何地方都可以使用公有派生類的對(duì)象來(lái)替代。
2、賦值兼容規(guī)則中所指的替代包括:
   派生類的對(duì)象可以賦值給基類對(duì)象;
   派生類的對(duì)象可以初始化基類的引用;
   派生類對(duì)象的地址可以賦給指向基類的指針。
   在替代之后,派生類對(duì)象就可以作為基類的對(duì)象使用,但只能使用從基類繼承的成員。
例子:
復(fù)制代碼
#include <iostream> #include <time.h> using namespace std; class B0 { public: void display() { cout<<"B0::display()"<<endl; } }; class B1:public B0 { public: void display() { cout<<"B1::display()"<<endl; } }; class B2:public B0 { public: void display() { cout<<"B2::display()"<<endl; } }; void fun(B0 *ptr) { ptr->display(); } int main() { B0 b0; B1 b1; B2 b2; fun(&b0); b0 = b1; fun(&b0); b0 = b2; fun(&b0); return 0; }
復(fù)制代碼

 

輸出結(jié)果為:

B0::display()

B0::display()

B0::display()

通過(guò)這種賦值兼容后,每次調(diào)用的同名函數(shù)都是基類的同名函數(shù),如果想調(diào)用派生類的,則需要使用虛函數(shù)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    日韩免费国产91在线| 日韩精品一区二区三区射精 | 国产情侣激情在线对白| 亚洲内射人妻一区二区| 欧洲日本亚洲一区二区| 五月激情五月天综合网| 91欧美一区二区三区成人| 国产精品一区二区高潮| 国产精品视频一区麻豆专区| 日本人妻中出在线观看| 一级片二级片欧美日韩| 97人妻精品一区二区三区免| 色小姐干香蕉在线综合网| 亚洲国产黄色精品在线观看 | 久久re6热在线视频| 欧洲偷拍视频中文字幕| 精品少妇一区二区视频| 日本人妻精品有码字幕| 噜噜中文字幕一区二区| 国产精品久久久久久久久久久痴汉| 日韩美成人免费在线视频| 日本久久精品在线观看| 亚洲a码一区二区三区| 午夜视频成人在线免费| 日韩精品一区二区三区av在线| 99一级特黄色性生活片| 国内九一激情白浆发布| 国产免费无遮挡精品视频| 午夜精品久久久99热连载| 日韩欧美一区二区黄色 | 中文字幕精品一区二区年下载| 99久久精品视频一区二区| 日本午夜福利视频免费观看| 懂色一区二区三区四区| 国产不卡视频一区在线| 国产精品日韩欧美第一页| 一级片二级片欧美日韩| 亚洲av专区在线观看| 午夜资源在线观看免费高清| 美女被后入视频在线观看| 亚洲精品小视频在线观看|