(C++-面向?qū)ο蟪绦蛟O(shè)計(jì)-譚浩強(qiáng))第11章-繼承與派生_第1頁(yè)
(C++-面向?qū)ο蟪绦蛟O(shè)計(jì)-譚浩強(qiáng))第11章-繼承與派生_第2頁(yè)
(C++-面向?qū)ο蟪绦蛟O(shè)計(jì)-譚浩強(qiáng))第11章-繼承與派生_第3頁(yè)
(C++-面向?qū)ο蟪绦蛟O(shè)計(jì)-譚浩強(qiáng))第11章-繼承與派生_第4頁(yè)
(C++-面向?qū)ο蟪绦蛟O(shè)計(jì)-譚浩強(qiáng))第11章-繼承與派生_第5頁(yè)
已閱讀5頁(yè),還剩31頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、精選優(yōu)質(zhì)文檔-傾情為你奉上第4篇 面向?qū)ο蟮某绦蛟O(shè)計(jì)第11章 繼承與派生第12章 多態(tài)性與虛函數(shù)第13章 輸入輸出流第14章 C+工具第11章 繼承與派生11.1 繼承與派生的概念11.2 派生類的聲明方式11.3 派生類的構(gòu)成11.4 派生類成員的訪問(wèn)屬性11.5 派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)11.6 多重繼承11.7 基類與派生類的轉(zhuǎn)換11.8 繼承與組合11.9 繼承在軟件開(kāi)發(fā)中的重要意義面向?qū)ο蟪绦蛟O(shè)計(jì)有4個(gè)主要特點(diǎn):抽象、封裝、繼承和多態(tài)性。要較好地進(jìn)行面向?qū)ο蟪绦蛟O(shè)計(jì),還必須了解面向?qū)ο蟪绦蛟O(shè)計(jì)另外兩個(gè)重要特征繼承性和多態(tài)性。在本章中主要介紹有關(guān)繼承的知識(shí),在第12章中將介紹多態(tài)性。

2、面向?qū)ο蠹夹g(shù)強(qiáng)調(diào)軟件的可重用性(software reusability)。C+語(yǔ)言提供了類的繼承機(jī)制,解決了軟件重用問(wèn)題。11.1 繼承與派生的概念在C+中可重用性是通過(guò)繼承(inheritance)這一機(jī)制來(lái)實(shí)現(xiàn)的。繼承是C+的一個(gè)重要組成部分。一個(gè)類中包含了若干數(shù)據(jù)成員和成員函數(shù)。在不同的類中,數(shù)據(jù)成員和成員函數(shù)是不相同的。但有時(shí)兩個(gè)類的內(nèi)容基本相同或有一部分相同。利用原來(lái)聲明的類Student作為基礎(chǔ),再加上新的內(nèi)容即可,以減少重復(fù)的工作量。C+提供的繼承機(jī)制就是為了解決這個(gè)問(wèn)題。在第8章已舉了馬的例子來(lái)說(shuō)明繼承的概念。見(jiàn)圖11.1示意。在C+中,所謂“繼承”就是在一個(gè)已存在的類的基礎(chǔ)

3、上建立一個(gè)新的類。已存在的類(例如“馬”)稱為“基類(base class )”或“父類(father class )”。新建的類(例如“公馬”)稱為“派生類(derived class )”或“子類(son class )”。見(jiàn)圖11.2示意。圖11.1圖11.2一個(gè)新類從已有的類那里獲得其已有特性,這種現(xiàn)象稱為類的繼承。通過(guò)繼承,一個(gè)新建子類從已有的父類那里獲得父類的特性。從另一角度說(shuō),從已有的類(父類)產(chǎn)生一個(gè)新的子類,稱為類的派生。類的繼承是用已有的類來(lái)建立專用類的編程技術(shù)。派生類繼承了基類的所有數(shù)據(jù)成員和成員函數(shù),并可以對(duì)成員作必要的增加或調(diào)整。一個(gè)基類可以派生出多個(gè)派生類,每一個(gè)派

4、生類又可以作為基類再派生出新的派生類,因此基類和派生類是相對(duì)而言的。以上介紹的是最簡(jiǎn)單的情況:一個(gè)派生類只從一個(gè)基類派生,這稱為單繼承(single inheritance),這種繼承關(guān)系所形成的層次是一個(gè)樹(shù)形結(jié)構(gòu),可以用圖11.3表示。圖11.3請(qǐng)注意圖中箭頭的方向,在本書(shū)中約定,箭頭表示繼承的方向,從派生類指向基類。一個(gè)派生類不僅可以從一個(gè)基類派生,也可以從多個(gè)基類派生。一個(gè)派生類有兩個(gè)或多個(gè)基類的稱為多重繼承(multiple inheritance), 這種繼承關(guān)系所形成的結(jié)構(gòu)如圖11.4所示。圖11.4關(guān)于基類和派生類的關(guān)系,可以表述為:派生類是基類的具體化,而基類則是派生類的抽象。

5、圖11.511.2 派生類的聲明方式假設(shè)已經(jīng)聲明了一個(gè)基類Student,在此基礎(chǔ)上通過(guò)單繼承建立一個(gè)派生類Student1:class Student1: public Student/聲明基類是Studentpublic:void display_1( )/新增加的成員函數(shù)cout<<age: <<age<<endl;cout<<address: <<addr<<endl;private :int age;/新增加的數(shù)據(jù)成員string addr;/新增加的數(shù)據(jù)成員;基類名前面有public的稱為“公用繼承(publi

6、c inheritance)”。聲明派生類的一般形式為class 派生類名:繼承方式 基類名派生類新增加的成員;繼承方式包括: public (公用的),private (私有的)和protected(受保護(hù)的),此項(xiàng)是可選的,如果不寫(xiě)此項(xiàng),則默認(rèn)為private(私有的)。11.3 派生類的構(gòu)成派生類中的成員包括從基類繼承過(guò)來(lái)的成員和自己增加的成員兩大部分。在基類中包括數(shù)據(jù)成員和成員函數(shù)(或稱數(shù)據(jù)與方法)兩部分,派生類分為兩大部分: 一部分是從基類繼承來(lái)的成員,另一部分是在聲明派生類時(shí)增加的部分。每一部分均分別包括數(shù)據(jù)成員和成員函數(shù)。圖11.6實(shí)際上,并不是把基類的成員和派生類自己增加的成員

7、簡(jiǎn)單地加在一起就成為派生類。構(gòu)造一個(gè)派生類包括以下3部分工作:(1) 從基類接收成員。派生類把基類全部的成員(不包括構(gòu)造函數(shù)和析構(gòu)函數(shù))接收過(guò)來(lái),也就是說(shuō)是沒(méi)有選擇的,不能選擇接收其中一部分成員,而舍棄另一部分成員。要求我們根據(jù)派生類的需要慎重選擇基類,使冗余量最小。事實(shí)上,有些類是專門(mén)作為基類而設(shè)計(jì)的,在設(shè)計(jì)時(shí)充分考慮到派生類的要求。(2) 調(diào)整從基類接收的成員。接收基類成員是程序人員不能選擇的,但是程序人員可以對(duì)這些成員作某些調(diào)整。(3) 在聲明派生類時(shí)增加的成員。這部分內(nèi)容是很重要的,它體現(xiàn)了派生類對(duì)基類功能的擴(kuò)展。要根據(jù)需要仔細(xì)考慮應(yīng)當(dāng)增加哪些成員,精心設(shè)計(jì)。此外,在聲明派生類時(shí),一般

8、還應(yīng)當(dāng)自己定義派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù),因?yàn)闃?gòu)造函數(shù)和析構(gòu)函數(shù)是不能從基類繼承的。派生類是基類定義的延續(xù)??梢韵嚷暶饕粋€(gè)基類,在此基類中只提供某些最基本的功能,而另外有些功能并未實(shí)現(xiàn),然后在聲明派生類時(shí)加入某些具體的功能,形成適用于某一特定應(yīng)用的派生類。通過(guò)對(duì)基類聲明的延續(xù),將一個(gè)抽象的基類轉(zhuǎn)化成具體的派生類。因此,派生類是抽象基類的具體實(shí)現(xiàn)。11.4 派生類成員的訪問(wèn)屬性既然派生類中包含基類成員和派生類自己增加的成員,就產(chǎn)生了這兩部分成員的關(guān)系和訪問(wèn)屬性的問(wèn)題。在建立派生類的時(shí)候,并不是簡(jiǎn)單地把基類的私有成員直接作為派生類的私有成員,把基類的公用成員直接作為派生類的公用成員。實(shí)際上,對(duì)基類

9、成員和派生類自己增加的成員是按不同的原則處理的。具體說(shuō),在討論訪問(wèn)屬性時(shí),要考慮以下幾種情況:(1) 基類的成員函數(shù)訪問(wèn)基類成員。(2) 派生類的成員函數(shù)訪問(wèn)派生類自己增加的成員。(3) 基類的成員函數(shù)訪問(wèn)派生類的成員。(4) 派生類的成員函數(shù)訪問(wèn)基類的成員。(5) 在派生類外訪問(wèn)派生類的成員。(6) 在派生類外訪問(wèn)基類的成員。對(duì)于第(1)和第(2)種情況,比較簡(jiǎn)單,按第8章介紹過(guò)的規(guī)則處理,即: 基類的成員函數(shù)可以訪問(wèn)基類成員,派生類的成員函數(shù)可以訪問(wèn)派生類成員。私有數(shù)據(jù)成員只能被同一類中的成員函數(shù)訪問(wèn),公用成員可以被外界訪問(wèn)。第(3)種情況也比較明確,基類的成員函數(shù)只能訪問(wèn)基類的成員,而不

10、能訪問(wèn)派生類的成員。第(5)種情況也比較明確,在派生類外可以訪問(wèn)派生類的公用成員,而不能訪問(wèn)派生類的私有成員。對(duì)于第(4)和第(6)種情況,就稍微復(fù)雜一些,也容易混淆。這些牽涉到如何確定基類的成員在派生類中的訪問(wèn)屬性的問(wèn)題,不僅要考慮對(duì)基類成員所聲明的訪問(wèn)屬性,還要考慮派生類所聲明的對(duì)基類的繼承方式,根據(jù)這兩個(gè)因素共同決定基類成員在派生類中的訪問(wèn)屬性。前面已提到: 在派生類中,對(duì)基類的繼承方式可以有public(公用的),private (私有的)和protected(保護(hù)的)3種。不同的繼承方式?jīng)Q定了基類成員在派生類中的訪問(wèn)屬性。簡(jiǎn)單地說(shuō):(1) 公用繼承(public inheritanc

11、e)基類的公用成員和保護(hù)成員在派生類中保持原有訪問(wèn)屬性,其私有成員仍為基類私有。(2) 私有繼承(private inheritance)基類的公用成員和保護(hù)成員在派生類中成了私有成員。其私有成員仍為基類私有。(3) 受保護(hù)的繼承(protected inheritance)基類的公用成員和保護(hù)成員在派生類中成了保護(hù)成員,其私有成員仍為基類私有。保護(hù)成員的意思是: 不能被外界引用,但可以被派生類的成員引用,具體的用法將在稍后介紹。11.4.1 公用繼承在定義一個(gè)派生類時(shí)將基類的繼承方式指定為public的,稱為公用繼承,用公用繼承方式建立的派生類稱為公用派生類(public derived c

12、lass ),其基類稱為公用基類(public base class )。采用公用繼承方式時(shí),基類的公用成員和保護(hù)成員在派生類中仍然保持其公用成員和保護(hù)成員的屬性,而基類的私有成員在派生類中并沒(méi)有成為派生類的私有成員,它仍然是基類的私有成員,只有基類的成員函數(shù)可以引用它,而不能被派生類的成員函數(shù)引用,因此就成為派生類中的不可訪問(wèn)的成員。公用基類的成員在派生類中的訪問(wèn)屬性見(jiàn)書(shū)中表11.1。例11.1 訪問(wèn)公有基類的成員。下面寫(xiě)出類的聲明部分:Class Student/聲明基類public : /基類公用成員void get_value( )cin>>num>>name&

13、gt;>sex;void display( )cout<< num: <<num<<endl;cout<< name: <<name<<endl;cout<< sex: <<sex<<endl;private : /基類私有成員int num; string name;char sex;class Student1: public Student /以public方式聲明派生類Student1public:void display_1( )cout<< num: <

14、;<num<<endl; /企圖引用基類的私有成員,錯(cuò)誤cout<< name: <<name<<endl; /企圖引用基類的私有成員,錯(cuò)誤cout<< sex: <<sex<<endl; /企圖引用基類的私有成員,錯(cuò)誤cout<< age: <<age<<endl; /引用派生類的私有成員,正確cout<< address: <<addr<<endl; /引用派生類的私有成員,正確private: int age;string ad

15、dr;由于基類的私有成員對(duì)派生類來(lái)說(shuō)是不可訪問(wèn)的,因此在派生類中的display_1函數(shù)中直接引用基類的私有數(shù)據(jù)成員num,name和sex是不允許的。只能通過(guò)基類的公用成員函數(shù)來(lái)引用基類的私有數(shù)據(jù)成員。可以將派生類Student1的聲明改為class Student1: public Student/以public方式聲明派生類Student1public:void display_1( ) cout<< age: <<age<<endl; /引用派生類的私有成員,正確cout<< address: <<addr<<en

16、dl; /引用派生類的私有成員,正確private:int age; string addr;然后在main函數(shù)中分別調(diào)用基類的display函數(shù)和派生類中的display_1函數(shù),先后輸出5個(gè)數(shù)據(jù)。可以這樣寫(xiě)main函數(shù)(假設(shè)對(duì)象stud中已有數(shù)據(jù)):int main( )Student1 stud;/定義派生類Student1的對(duì)象studstud.display( );/調(diào)用基類的公用成員函數(shù),輸出基類中3個(gè)數(shù)據(jù)成員的值stud.display_1();/調(diào)用派生類公用成員函數(shù),輸出派生類中兩個(gè)數(shù)據(jù)成員的值return 0;請(qǐng)根據(jù)上面的分析,寫(xiě)出完整的程序,程序中應(yīng)包括輸入數(shù)據(jù)的函數(shù)。實(shí)

17、際上,程序還可以改進(jìn),在派生類的display_1函數(shù)中調(diào)用基類的display函數(shù),在主函數(shù)中只要寫(xiě)一行:stud.display_1(); 即可輸出5個(gè)數(shù)據(jù)。11.4.2 私有繼承在聲明一個(gè)派生類時(shí)將基類的繼承方式指定為private的,稱為私有繼承,用私有繼承方式建立的派生類稱為私有派生類(private derived class ) , 其基類稱為私有基類(private base class )。私有基類的公用成員和保護(hù)成員在派生類中的訪問(wèn)屬性相當(dāng)于派生類中的私有成員,即派生類的成員函數(shù)能訪問(wèn)它們,而在派生類外不能訪問(wèn)它們。私有基類的私有成員在派生類中成為不可訪問(wèn)的成員,只有基類的

18、成員函數(shù)可以引用它們。一個(gè)基類成員在基類中的訪問(wèn)屬性和在派生類中的訪問(wèn)屬性可能是不同的。私有基類的成員在私有派生類中的訪問(wèn)屬性見(jiàn)書(shū)中表11.2。圖11.7圖11.7表示了各成員在派生類中的訪問(wèn)屬性。對(duì)表11.2的規(guī)定不必死記,只需理解: 既然聲明為私有繼承,就表示將原來(lái)能被外界引用的成員隱藏起來(lái),不讓外界引用,因此私有基類的公用成員和保護(hù)成員理所當(dāng)然地成為派生類中的私有成員。私有基類的私有成員按規(guī)定只能被基類的成員函數(shù)引用,在基類外當(dāng)然不能訪問(wèn)他們,因此它們?cè)谂缮愔惺请[蔽的,不可訪問(wèn)的。對(duì)于不需要再往下繼承的類的功能可以用私有繼承方式把它隱蔽起來(lái),這樣,下一層的派生類無(wú)法訪問(wèn)它的任何成員???/p>

19、以知道: 一個(gè)成員在不同的派生層次中的訪問(wèn)屬性可能是不同的。它與繼承方式有關(guān)。例11.2 將例11.1中的公用繼承方式改為用私有繼承方式(基類Student不改)。可以寫(xiě)出私有派生類如下:class Student1: private Student/用私有繼承方式聲明派生類Student1public:void display_1( ) /輸出兩個(gè)數(shù)據(jù)成員的值cout<<age: <<age<<endl; /引用派生類的私有成員,正確cout<<address: <<addr<<endl; /引用派生類的私有成員,正確p

20、rivate:int age; string addr;請(qǐng)分析下面的主函數(shù):int main( )Student1 stud1;/定義一個(gè)Student1類的對(duì)象stud1stud1.display(); /錯(cuò)誤,私有基類的公用成員函數(shù)在派生類中是私有函數(shù)stud1.display_1( );/正確。Display_1函數(shù)是Student1類的公用函數(shù)stud1.age=18; /錯(cuò)誤。外界不能引用派生類的私有成員return 0;可以看到:(1) 不能通過(guò)派生類對(duì)象(如stud1)引用從私有基類繼承過(guò)來(lái)的任何成員(如stud1.display()或stud1.num)。(2) 派生類的成員函

21、數(shù)不能訪問(wèn)私有基類的私有成員,但可以訪問(wèn)私有基類的公用成員(如stud1.display_1函數(shù)可以調(diào)用基類的公用成員函數(shù)display,但不能引用基類的私有成員num)。有沒(méi)有辦法調(diào)用私有基類的公用成員函數(shù),從而引用私有基類的私有成員呢?有。應(yīng)當(dāng)注意到: 雖然在派生類外不能通過(guò)派生類對(duì)象調(diào)用私有基類的公用成員函數(shù),但可以通過(guò)派生類的成員函數(shù)調(diào)用私有基類的公用成員函數(shù)(此時(shí)它是派生類中的私有成員函數(shù),可以被派生類的任何成員函數(shù)調(diào)用)??蓪⑸厦娴乃接信缮惖某蓡T函數(shù)定義改寫(xiě)為void display_1( )/輸出5個(gè)數(shù)據(jù)成員的值display(): /調(diào)用基類的公用成員函數(shù),輸出3個(gè)數(shù)據(jù)成員的

22、值cout<<age: <<age<<endl; /輸出派生類的私有數(shù)據(jù)成員cout<<address: <<addr<<endl; /輸出派生類的私有數(shù)據(jù)成員main函數(shù)可改寫(xiě)為int main( )Student1 stud1;stud1.display_1( );/display_1函數(shù)是派生類Student1類的公用函數(shù)return 0;這樣就能正確地引用私有基類的私有成員??梢钥吹剑纠捎玫姆椒ㄊ? 在main函數(shù)中調(diào)用派生類中的公用成員函數(shù)stud1.display_1; 通過(guò)該公用成員函數(shù)調(diào)用基類的公用成員

23、函數(shù)display(它在派生類中是私有函數(shù),可以被派生類中的任何成員函數(shù)調(diào)用); 通過(guò)基類的公用成員函數(shù)display引用基類中的數(shù)據(jù)成員。請(qǐng)根據(jù)上面的要求,補(bǔ)充和完善上面的程序,使之成為完整、正確的程序。程序中應(yīng)包括輸入數(shù)據(jù)的函數(shù)。由于私有派生類限制太多,使用不方便,一般不常使用。11.4.3 保護(hù)成員和保護(hù)繼承由protected聲明的成員稱為“受保護(hù)的成員”,或簡(jiǎn)稱“保護(hù)成員”。從類的用戶角度來(lái)看,保護(hù)成員等價(jià)于私有成員。但有一點(diǎn)與私有成員不同,保護(hù)成員可以被派生類的成員函數(shù)引用。見(jiàn)圖11.8示意。圖11.8如果基類聲明了私有成員,那么任何派生類都是不能訪問(wèn)它們的,若希望在派生類中能訪問(wèn)

24、它們,應(yīng)當(dāng)把它們聲明為保護(hù)成員。如果在一個(gè)類中聲明了保護(hù)成員,就意味著該類可能要用作基類,在它的派生類中會(huì)訪問(wèn)這些成員。在定義一個(gè)派生類時(shí)將基類的繼承方式指定為protected的,稱為保護(hù)繼承,用保護(hù)繼承方式建立的派生類稱為保護(hù)派生類(protected derived class ), 其基類稱為受保護(hù)的基類(protected base class ),簡(jiǎn)稱保護(hù)基類。保護(hù)繼承的特點(diǎn)是: 保護(hù)基類的公用成員和保護(hù)成員在派生類中都成了保護(hù)成員,其私有成員仍為基類私有。也就是把基類原有的公用成員也保護(hù)起來(lái),不讓類外任意訪問(wèn)。將表11.1和表11.2綜合起來(lái),并增加保護(hù)繼承的內(nèi)容,見(jiàn)書(shū)中表11.

25、3。保護(hù)基類的所有成員在派生類中都被保護(hù)起來(lái),類外不能訪問(wèn),其公用成員和保護(hù)成員可以被其派生類的成員函數(shù)訪問(wèn)。比較一下私有繼承和保護(hù)繼承(也就是比較在私有派生類中和在保護(hù)派生類中的訪問(wèn)屬性), 可以發(fā)現(xiàn),在直接派生類中,以上兩種繼承方式的作用實(shí)際上是相同的: 在類外不能訪問(wèn)任何成員,而在派生類中可以通過(guò)成員函數(shù)訪問(wèn)基類中的公用成員和保護(hù)成員。但是如果繼續(xù)派生,在新的派生類中,兩種繼承方式的作用就不同了。例如,如果以公用繼承方式派生出一個(gè)新派生類,原來(lái)私有基類中的成員在新派生類中都成為不可訪問(wèn)的成員,無(wú)論在派生類內(nèi)或外都不能訪問(wèn),而原來(lái)保護(hù)基類中的公用成員和保護(hù)成員在新派生類中為保護(hù)成員,可以被

26、新派生類的成員函數(shù)訪問(wèn)。從表11.3可知: 基類的私有成員被派生類繼承后變?yōu)椴豢稍L問(wèn)的成員,派生類中的一切成員均無(wú)法訪問(wèn)它們。如果需要在派生類中引用基類的某些成員,應(yīng)當(dāng)將基類的這些成員聲明為protected,而不要聲明為private。如果善于利用保護(hù)成員,可以在類的層次結(jié)構(gòu)中找到數(shù)據(jù)共享與成員隱蔽之間的結(jié)合點(diǎn)。既可實(shí)現(xiàn)某些成員的隱蔽,又可方便地繼承,能實(shí)現(xiàn)代碼重用與擴(kuò)充。通過(guò)以上的介紹,可以知道:(1) 在派生類中,成員有4種不同的訪問(wèn)屬性: 公用的,派生類內(nèi)和派生類外都可以訪問(wèn)。 受保護(hù)的,派生類內(nèi)可以訪問(wèn),派生類外不能訪問(wèn),其下一層的派生類可以訪問(wèn)。 私有的,派生類內(nèi)可以訪問(wèn),派生類外

27、不能訪問(wèn)。 不可訪問(wèn)的,派生類內(nèi)和派生類外都不能訪問(wèn)??梢杂脮?shū)中表11.4表示。需要說(shuō)明的是: 這里所列出的成員的訪問(wèn)屬性是指在派生類中所獲得的訪問(wèn)屬性。 所謂在派生類外部,是指在建立派生類對(duì)象的模塊中,在派生類范圍之外。 如果本派生類繼續(xù)派生,則在不同的繼承方式下,成員所獲得的訪問(wèn)屬性是不同的,在本表中只列出在下一層公用派生類中的情況,如果是私有繼承或保護(hù)繼承,讀者可以從表11.3中找到答案。(2) 類的成員在不同作用域中有不同的訪問(wèn)屬性,對(duì)這一點(diǎn)要十分清楚。下面通過(guò)一個(gè)例子說(shuō)明怎樣訪問(wèn)保護(hù)成員。例11.3 在派生類中引用保護(hù)成員。#include <iostream>#incl

28、ude <string>using namespace std;class Student/聲明基類public : /基類公用成員void display( );protected:/基類保護(hù)成員int num;string name;char sex;/定義基類成員函數(shù)void Student:display( ) cout<<num: <<num<<endl;cout<<name: <<name<<endl;cout<<sex: <<sex<<endl;class St

29、udent1: protectedStudent /用protected方式聲明派生類Student1public : void display1( );/派生類公用成員函數(shù)private : int age;/派生類私有數(shù)據(jù)成員string addr;/派生類私有數(shù)據(jù)成員;void Student1:display1( )/定義派生類公用成員函數(shù)cout<<num: <<num<<endl;/引用基類的保護(hù)成員,合法cout<<name: <<name<<endl;/引用基類的保護(hù)成員,合法cout<<sex

30、: <<sex<<endl;/引用基類的保護(hù)成員,合法cout<<age: <<age<<endl;/引用派生類的私有成員,合法cout<<address: <<addr<<endl; /引用派生類的私有成員,合法int main( )Student1 stud1; /stud1是派生類Student1類的對(duì)象stud1.display1( ); /合法,display1是派生類中的公用成員函數(shù)stud1.num=10023; /錯(cuò)誤,外界不能訪問(wèn)保護(hù)成員return 0;在派生類的成員函數(shù)中引用基

31、類的保護(hù)成員是合法的。保護(hù)成員和私有成員不同之處,在于把保護(hù)成員的訪問(wèn)范圍擴(kuò)展到派生類中。注意: 在程序中通過(guò)派生類Student1的對(duì)象stud1的公用成員函數(shù)display1去訪問(wèn)基類的保護(hù)成員和sex,不要誤認(rèn)為可以通過(guò)派生類對(duì)象名去訪問(wèn)基類的保護(hù)成員。請(qǐng)補(bǔ)充、修改上面的程序,使之能正常運(yùn)行。程序中應(yīng)包括輸入數(shù)據(jù)的函數(shù)。私有繼承和保護(hù)繼承方式在使用時(shí)需要十分小心,很容易搞錯(cuò),一般不常用。11.4.4 多級(jí)派生時(shí)的訪問(wèn)屬性圖11.9如果有圖11.9所示的派生關(guān)系: 類A為基類,類B是類A的派生類,類C是類B的派生類,則類C也是類A的派生類。類B稱為類A的直接派生類,類C稱為

32、類A的間接派生類。類A是類B的直接基類,是類C的間接基類。在多級(jí)派生的情況下,各成員的訪問(wèn)屬性仍按以上原則確定。例11.4 多級(jí)派生的訪問(wèn)屬性。如果聲明了以下的類: class A /基類public:int i;protected :void f2( );int j;private :int k;class B: public A/public方式public :void f3( );protected :void f4( );private :int m;class C: protected B /protected方式public :void f5( );private :int n;類

33、A是類B的公用基類,類B是類C的保護(hù)基類。各成員在不同類中的訪問(wèn)屬性如下: 無(wú)論哪一種繼承方式,在派生類中是不能訪問(wèn)基類的私有成員的,私有成員只能被本類的成員函數(shù)所訪問(wèn),畢竟派生類與基類不是同一個(gè)類。如果在多級(jí)派生時(shí)都采用公用繼承方式,那么直到最后一級(jí)派生類都能訪問(wèn)基類的公用成員和保護(hù)成員。如果采用私有繼承方式,經(jīng)過(guò)若干次派生之后,基類的所有的成員已經(jīng)變成不可訪問(wèn)的了。如果采用保護(hù)繼承方式,在派生類外是無(wú)法訪問(wèn)派生類中的任何成員的。而且經(jīng)過(guò)多次派生后,人們很難清楚地記住哪些成員可以訪問(wèn),哪些成員不能訪問(wèn),很容易出錯(cuò)。因此,在實(shí)際中,常用的是公用繼承。11.5 派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)用戶在聲

34、明類時(shí)可以不定義構(gòu)造函數(shù),系統(tǒng)會(huì)自動(dòng)設(shè)置一個(gè)默認(rèn)的構(gòu)造函數(shù),在定義類對(duì)象時(shí)會(huì)自動(dòng)調(diào)用這個(gè)默認(rèn)的構(gòu)造函數(shù)。這個(gè)構(gòu)造函數(shù)實(shí)際上是一個(gè)空函數(shù),不執(zhí)行任何操作。如果需要對(duì)類中的數(shù)據(jù)成員初始化,應(yīng)自己定義構(gòu)造函數(shù)。構(gòu)造函數(shù)的主要作用是對(duì)數(shù)據(jù)成員初始化。在設(shè)計(jì)派生類的構(gòu)造函數(shù)時(shí),不僅要考慮派生類所增加的數(shù)據(jù)成員的初始化,還應(yīng)當(dāng)考慮基類的數(shù)據(jù)成員初始化。也就是說(shuō),希望在執(zhí)行派生類的構(gòu)造函數(shù)時(shí),使派生類的數(shù)據(jù)成員和基類的數(shù)據(jù)成員同時(shí)都被初始化。解決這個(gè)問(wèn)題的思路是: 在執(zhí)行派生類的構(gòu)造函數(shù)時(shí),調(diào)用基類的構(gòu)造函數(shù)。11.5.1 簡(jiǎn)單的派生類的構(gòu)造函數(shù)任何派生類都包含基類的成員,簡(jiǎn)單的派生類只有一個(gè)基類,而且只有

35、一級(jí)派生(只有直接派生類,沒(méi)有間接派生類),在派生類的數(shù)據(jù)成員中不包含基類的對(duì)象(即子對(duì)象)。例11.5 簡(jiǎn)單的派生類的構(gòu)造函數(shù)。#include <iostream>#include<string>using namespace std;class Student/聲明基類Studentpublic:Student(int n,string nam,char s) /基類構(gòu)造函數(shù)num=n; name=nam; sex=s; Student( ) /基類析構(gòu)函數(shù)protected : /保護(hù)部分int num;string name;char sex ;class S

36、tudent1: public Student /聲明派生類Student1public : /派生類的公用部分Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s)/派生類構(gòu)造函數(shù)age=a; /在函數(shù)體中只對(duì)派生類新增的數(shù)據(jù)成員初始化addr=ad; void show( )cout<<num: <<num<<endl; cout<<name: <<name<<endl; cout<<sex: <<sex<<

37、;endl; cout<<age: <<age<<endl; cout<<address: <<addr<<endl<<endl;Student1( ) /派生類析構(gòu)函數(shù)private : /派生類的私有部分int age;string addr;int main( )Student1 stud1(10010,Wang-li,f,19,115 Beijing Road,Shanghai); Student1 stud2(10011,Zhang-fun,m,21,213 Shanghai Road,Beijing

38、); stud1.show( ); /輸出第一個(gè)學(xué)生的數(shù)據(jù) stud2.show( ); /輸出第二個(gè)學(xué)生的數(shù)據(jù)return 0;運(yùn)行結(jié)果為num:10010name:Wang-lisex:faddress: 115Beijing Road,Shanghainum:10011name:Zhang-funsex:maddress: 213Shanghai Road,Beijing請(qǐng)注意派生類構(gòu)造函數(shù)首行的寫(xiě)法: Student1(int n, string nam, char s, int a, string ad):Student(n, nam, s)其一般形式為派生類構(gòu)造函數(shù)名(總參數(shù)表列)

39、:基類構(gòu)造函數(shù)名(參數(shù)表列)派生類中新增數(shù)據(jù)成員初始化語(yǔ)句在main函數(shù)中,建立對(duì)象stud1時(shí)指定了5個(gè)實(shí)參。它們按順序傳遞給派生類構(gòu)造函數(shù)Student1的形參。然后,派生類構(gòu)造函數(shù)將前面3個(gè)傳遞給基類構(gòu)造函數(shù)的形參。見(jiàn)圖11.10。圖11.10通過(guò)Student (n, nam, s)把3個(gè)值再傳給基類構(gòu)造函數(shù)的形參,見(jiàn)圖11.11。Student( n, nam, s) Student(int n, string nam, char s)/這是基類構(gòu)造函數(shù)的首部圖11.11在上例中也可以將派生類構(gòu)造函數(shù)在類外面定義,而在類體中只寫(xiě)該函數(shù)的聲明: Student1(int n, stri

40、ng nam, char s, int a, string ad);在類的外面定義派生類構(gòu)造函數(shù):Student1Student1(int n,string nam,char s,int a,string ad):Student(n,nam,s)age=a;addr=ad; 請(qǐng)注意: 在類中對(duì)派生類構(gòu)造函數(shù)作聲明時(shí),不包括基類構(gòu)造函數(shù)名及其參數(shù)表列(即Student(n, nam, s))。只在定義函數(shù)時(shí)才將它列出。在以上的例子中,調(diào)用基類構(gòu)造函數(shù)時(shí)的實(shí)參是從派生類構(gòu)造函數(shù)的總參數(shù)表中得到的,也可以不從派生類構(gòu)造函數(shù)的總參數(shù)表中傳遞過(guò)來(lái),而直接使用常量或全局變量。例如,派生類構(gòu)造函數(shù)首行可以寫(xiě)

41、成以下形式:Student1(string nam,char s,int a,string ad):Student(10010,nam,s)即基類構(gòu)造函數(shù)3個(gè)實(shí)參中,有一個(gè)是常量10010,另外兩個(gè)從派生類構(gòu)造函數(shù)的總參數(shù)表傳遞過(guò)來(lái)。請(qǐng)回顧一下在第9章介紹過(guò)的構(gòu)造函數(shù)初始化表的例子:Box:Box(int h,int w,int len):height(h),width(w),length(len) 它也有一個(gè)冒號(hào),在冒號(hào)后面的是對(duì)數(shù)據(jù)成員的初始化表。實(shí)際上,本章介紹的在派生類構(gòu)造函數(shù)中對(duì)基類成員初始化,就是在第9章介紹的構(gòu)造函數(shù)初始化表。也就是說(shuō),不僅可以利用初始化表對(duì)構(gòu)造函數(shù)的數(shù)據(jù)成員初始

42、化,而且可以利用初始化表調(diào)用派生類的基類構(gòu)造函數(shù),實(shí)現(xiàn)對(duì)基類數(shù)據(jù)成員的初始化。也可以在同一個(gè)構(gòu)造函數(shù)的定義中同時(shí)實(shí)現(xiàn)這兩種功能。例如,例11.5中派生類的基類構(gòu)造函數(shù)的定義采用了下面的形式:Student1(int n, string nam,char s,int a, string ad):Student(n,nam,s)age=a;/在函數(shù)體中對(duì)派生類數(shù)據(jù)成員初始化 addr=ad;可以將對(duì)age和addr的初始化也用初始化表處理,將構(gòu)造函數(shù)改寫(xiě)為以下形式: Student1(int n, string nam,char s,int a, string ad):Student(n,nam,

43、s),age(a),addr(ad) 這樣函數(shù)體為空,更顯得簡(jiǎn)單和方便。在建立一個(gè)對(duì)象時(shí),執(zhí)行構(gòu)造函數(shù)的順序是:派生類構(gòu)造函數(shù)先調(diào)用基類構(gòu)造函數(shù);再執(zhí)行派生類構(gòu)造函數(shù)本身(即派生類構(gòu)造函數(shù)的函數(shù)體)。對(duì)上例來(lái)說(shuō),先初始化num,name,sex,然后再初始化age和addr。在派生類對(duì)象釋放時(shí),先執(zhí)行派生類析構(gòu)函數(shù)Student1( ),再執(zhí)行其基類析構(gòu)函數(shù)Student( )。11.5.2 有子對(duì)象的派生類的構(gòu)造函數(shù)類的數(shù)據(jù)成員中還可以包含類對(duì)象,如可以在聲明一個(gè)類時(shí)包含這樣的數(shù)據(jù)成員:Student s1;/ Student是已聲明的類名,s1是Student類的對(duì)象這時(shí),s1就是類對(duì)象中

44、的內(nèi)嵌對(duì)象,稱為子對(duì)象(subobject),即對(duì)象中的對(duì)象。通過(guò)例子來(lái)說(shuō)明問(wèn)題。例11.6 包含子對(duì)象的派生類的構(gòu)造函數(shù)。為了簡(jiǎn)化程序以易于閱讀,這里設(shè)基類Student的數(shù)據(jù)成員只有兩個(gè),即num和name。#include <iostream>#include <string>using namespace std;class Student/聲明基類public : /公用部分Student(int n, string nam ) /基類構(gòu)造函數(shù),與例11.5相同num=n;name=nam; void display( ) /成員函數(shù),輸出基類數(shù)據(jù)成員cout

45、<<num:<<num<<endl<<name:<<name<<endl;protected : /保護(hù)部分int num;string name;class Student1: public Student /聲明公用派生類Student1public:Student1(int n, string nam,int n1, string nam1,int a, string ad):Student(n,nam),monitor(n1,nam1) /派生類構(gòu)造函數(shù)age=a; addr=ad;void show( )cout

46、<<This student is:<<endl;display(); /輸出num和name cout<<age: <<age<<endl; /輸出age cout<<address: <<addr<<endl<<endl; /輸出addrvoid show_monitor( ) /成員函數(shù),輸出子對(duì)象cout<<endl<<Class monitor is:<<endl; monitor.display( ); /調(diào)用基類成員函數(shù)private :

47、 /派生類的私有數(shù)據(jù)Student monitor; /定義子對(duì)象(班長(zhǎng))int age;string addr;int main( )Student1 stud1(10010,Wang-li,10001,Li-sun,19,115 Beijing Road,Shanghai);stud1.show( ); /輸出學(xué)生的數(shù)據(jù)stud1.show_monitor(); /輸出子對(duì)象的數(shù)據(jù)return 0;運(yùn)行時(shí)的輸出如下:This student is:num: 10010name: Wang-liage: 19address:115 Beijing Road,ShanghaiClass mon

48、itor is:num:10001name:Li-sun派生類構(gòu)造函數(shù)的任務(wù)應(yīng)該包括3個(gè)部分:(1) 對(duì)基類數(shù)據(jù)成員初始化;(2) 對(duì)子對(duì)象數(shù)據(jù)成員初始化;(3) 對(duì)派生類數(shù)據(jù)成員初始化。程序中派生類構(gòu)造函數(shù)首部如下:Student1(int n, string nam,int n1, string nam1,int a, string ad): Student(n,nam),monitor(n1,nam1)在上面的構(gòu)造函數(shù)中有6個(gè)形參,前兩個(gè)作為基類構(gòu)造函數(shù)的參數(shù),第3、第4個(gè)作為子對(duì)象構(gòu)造函數(shù)的參數(shù),第5、第6個(gè)是用作派生類數(shù)據(jù)成員初始化的。見(jiàn)圖11.12。圖11.12歸納起來(lái),定義派生類

49、構(gòu)造函數(shù)的一般形式為派生類構(gòu)造函數(shù)名(總參數(shù)表列):基類構(gòu)造函數(shù)名(參數(shù)表列),子對(duì)象名(參數(shù)表列)派生類中新增數(shù)成員據(jù)成員初始化語(yǔ)句執(zhí)行派生類構(gòu)造函數(shù)的順序是: 調(diào)用基類構(gòu)造函數(shù),對(duì)基類數(shù)據(jù)成員初始化; 調(diào)用子對(duì)象構(gòu)造函數(shù),對(duì)子對(duì)象數(shù)據(jù)成員初始化; 再執(zhí)行派生類構(gòu)造函數(shù)本身,對(duì)派生類數(shù)據(jù)成員初始化。派生類構(gòu)造函數(shù)的總參數(shù)表列中的參數(shù),應(yīng)當(dāng)包括基類構(gòu)造函數(shù)和子對(duì)象的參數(shù)表列中的參數(shù)?;悩?gòu)造函數(shù)和子對(duì)象的次序可以是任意的,如上面的派生類構(gòu)造函數(shù)首部可以寫(xiě)成Student1(int n, string nam,int n1, string nam1,int a, string ad): moni

50、tor(n1,nam1),Student(n,nam)編譯系統(tǒng)是根據(jù)相同的參數(shù)名(而不是根據(jù)參數(shù)的順序)來(lái)確立它們的傳遞關(guān)系的。但是習(xí)慣上一般先寫(xiě)基類構(gòu)造函數(shù)。如果有多個(gè)子對(duì)象,派生類構(gòu)造函數(shù)的寫(xiě)法依此類推,應(yīng)列出每一個(gè)子對(duì)象名及其參數(shù)表列。11.5.3 多層派生時(shí)的構(gòu)造函數(shù)一個(gè)類不僅可以派生出一個(gè)派生類,派生類還可以繼續(xù)派生,形成派生的層次結(jié)構(gòu)。在上面敘述的基礎(chǔ)上,不難寫(xiě)出在多級(jí)派生情況下派生類的構(gòu)造函數(shù)。例11.7 多級(jí)派生情況下派生類的構(gòu)造函數(shù)。#include <iostream>#include<string>using namespace std;class

51、 Student/聲明基類public :/公用部分Student(int n, string nam)/基類構(gòu)造函數(shù)num=n;name=nam; void display( )/輸出基類數(shù)據(jù)成員cout<<num:<<num<<endl;cout<<name:<<name<<endl; protected :/保護(hù)部分int num;/基類有兩個(gè)數(shù)據(jù)成員string name; ; class Student1: public Student/聲明公用派生類Student1public :Student1(int n,

52、char nam10,int a):Student(n,nam)/派生類構(gòu)造函數(shù)age=a; /在此處只對(duì)派生類新增的數(shù)據(jù)成員初始化void show( ) /輸出num,name和agedisplay( ); /輸出num和namecout<<age: <<age<<endl; private :/派生類的私有數(shù)據(jù)int age; /增加一個(gè)數(shù)據(jù)成員;class Student2:public Student1 /聲明間接公用派生類Student2public:/下面是間接派生類構(gòu)造函數(shù)Student2(int n, string nam,int a,in

53、t s):Student1(n,nam,a) score=s;void show_all( ) /輸出全部數(shù)據(jù)成員show( ); /輸出num和namecout<<score:<<score<<endl; /輸出ageprivate:int score; /增加一個(gè)數(shù)據(jù)成員;int main( )Student2 stud(10010,Li,17,89);stud.show_all( ); /輸出學(xué)生的全部數(shù)據(jù)return 0;運(yùn)行時(shí)的輸出如下:num:10010name:Liage:17score:89其派生關(guān)系如圖11.13所示。圖11.13請(qǐng)注意基類

54、和兩個(gè)派生類的構(gòu)造函數(shù)的寫(xiě)法:基類的構(gòu)造函數(shù)首部:Student(int n, string nam)派生類Student1的構(gòu)造函數(shù)首部:Student1(int n, string nam,int a):Student(n,nam)派生類Student2的構(gòu)造函數(shù)首部:Student2(int n, string nam,int a,int ):Student1(n,nam,a)在聲明Student2類對(duì)象時(shí),調(diào)用Student2構(gòu)造函數(shù);在執(zhí)行Student2構(gòu)造函數(shù)時(shí),先調(diào)用Student1構(gòu)造函數(shù);在執(zhí)行Student1構(gòu)造函數(shù)時(shí),先調(diào)用基類Student構(gòu)造函數(shù)。初始化的順序是:

55、先初始化基類的數(shù)據(jù)成員num和name。 再初始化Student1的數(shù)據(jù)成員age。 最后再初始化Student2的數(shù)據(jù)成員score。11.5.4 派生類構(gòu)造函數(shù)的特殊形式在使用派生類構(gòu)造函數(shù)時(shí),有以下特殊的形式:(1) 當(dāng)不需要對(duì)派生類新增的成員進(jìn)行任何初始化操作時(shí),派生類構(gòu)造函數(shù)的函數(shù)體可以為空,即構(gòu)造函數(shù)是空函數(shù),如例11.6程序中派生類Student1構(gòu)造函數(shù)可以改寫(xiě)為Student1(int n, strin nam,int n1, strin nam1):Student(n,nam),monitor(n1,nam1) 此派生類構(gòu)造函數(shù)的作用只是為了將參數(shù)傳遞給基類構(gòu)造函數(shù)和子對(duì)象

56、,并在執(zhí)行派生類構(gòu)造函數(shù)時(shí)調(diào)用基類構(gòu)造函數(shù)和子對(duì)象構(gòu)造函數(shù)。在實(shí)際工作中常見(jiàn)這種用法。(2) 如果在基類中沒(méi)有定義構(gòu)造函數(shù),或定義了沒(méi)有參數(shù)的構(gòu)造函數(shù),那么在定義派生類構(gòu)造函數(shù)時(shí)可不寫(xiě)基類構(gòu)造函數(shù)。因?yàn)榇藭r(shí)派生類構(gòu)造函數(shù)沒(méi)有向基類構(gòu)造函數(shù)傳遞參數(shù)的任務(wù)。調(diào)用派生類構(gòu)造函數(shù)時(shí)系統(tǒng)會(huì)自動(dòng)首先調(diào)用基類的默認(rèn)構(gòu)造函數(shù)。如果在基類和子對(duì)象類型的聲明中都沒(méi)有定義帶參數(shù)的構(gòu)造函數(shù),而且也不需對(duì)派生類自己的數(shù)據(jù)成員初始化,則可以不必顯式地定義派生類構(gòu)造函數(shù)。因?yàn)榇藭r(shí)派生類構(gòu)造函數(shù)既沒(méi)有向基類構(gòu)造函數(shù)和子對(duì)象構(gòu)造函數(shù)傳遞參數(shù)的任務(wù),也沒(méi)有對(duì)派生類數(shù)據(jù)成員初始化的任務(wù)。在建立派生類對(duì)象時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)用系統(tǒng)提供的

57、派生類的默認(rèn)構(gòu)造函數(shù),并在執(zhí)行派生類默認(rèn)構(gòu)造函數(shù)的過(guò)程中,調(diào)用基類的默認(rèn)構(gòu)造函數(shù)和子對(duì)象類型默認(rèn)構(gòu)造函數(shù)。如果在基類或子對(duì)象類型的聲明中定義了帶參數(shù)的構(gòu)造函數(shù),那么就必須顯式地定義派生類構(gòu)造函數(shù),并在派生類構(gòu)造函數(shù)中寫(xiě)出基類或子對(duì)象類型的構(gòu)造函數(shù)及其參數(shù)表。如果在基類中既定義無(wú)參的構(gòu)造函數(shù),又定義了有參的構(gòu)造函數(shù)(構(gòu)造函數(shù)重載),則在定義派生類構(gòu)造函數(shù)時(shí),既可以包含基類構(gòu)造函數(shù)及其參數(shù),也可以不包含基類構(gòu)造函數(shù)。在調(diào)用派生類構(gòu)造函數(shù)時(shí),根據(jù)構(gòu)造函數(shù)的內(nèi)容決定調(diào)用基類的有參的構(gòu)造函數(shù)還是無(wú)參的構(gòu)造函數(shù)。編程者可以根據(jù)派生類的需要決定采用哪一種方式。11.5.5 派生類的析構(gòu)函數(shù)在派生時(shí),派生類是不能繼承基類的析構(gòu)函數(shù)的,也需要通過(guò)派生類的析構(gòu)函數(shù)去調(diào)用基類的析構(gòu)函數(shù)。在派生類中可以根據(jù)需要定義自己的析構(gòu)函數(shù),用來(lái)對(duì)派生類中所增加的成員進(jìn)行清理工作。基類的清理工作仍然由基類的析構(gòu)函數(shù)負(fù)責(zé)。在執(zhí)行派生類的析構(gòu)函數(shù)時(shí),系統(tǒng)會(huì)自動(dòng)調(diào)用基類的析構(gòu)函數(shù)和子對(duì)象的析構(gòu)函數(shù),對(duì)基類和子對(duì)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論