Fucking in c++第十三章筆記
1、組合就是由類成員(或稱成員類)組成新類
2、繼承實(shí)際上也是由基類做子成組成新類,但語(yǔ)法上有不同,體現(xiàn)了OOP的思想
基類在繼承類中默認(rèn)是私有的,以Y:public X形式繼承則變?yōu)楣小?/span>
從繼承類的外部調(diào)用基類的任何成員都要加上基類名,如Y y; y.X::f( ); 而對(duì)于成員類則要加上對(duì)象名y.x.f( );
3 由于C++強(qiáng)制初始化,因此基類和成員類都必須在新類的構(gòu)造函數(shù)初始化列表中初始化
初始化語(yǔ)法:對(duì)于基類,使用類名調(diào)用構(gòu)造函數(shù);對(duì)于成員類,使用對(duì)象名調(diào)用構(gòu)造函數(shù),如Y::Y(int i):X(i), x(i) {}
4 繼承類默認(rèn)繼承了基類的成員函數(shù),即,在不重定義的前提下,y.f( )和y.X::f( )調(diào)用的同一個(gè)函數(shù)
而組合類則必須通過(guò)成員類對(duì)象進(jìn)行函數(shù)調(diào)用
繼承類和組合類的構(gòu)/析造函數(shù)調(diào)用次序相反,前者從基類到子類5 如果重定義了基類的函數(shù),則基類的同名函數(shù)全部自動(dòng)隱藏。
所謂“全部”是因?yàn)椋赡茉诨愔杏卸鄠€(gè)同名的重載函數(shù),它們?nèi)侩[藏
所謂“隱藏”不是說(shuō)不能調(diào)用,而是說(shuō),當(dāng)調(diào)用y.f( )時(shí)調(diào)用的是Y中定義的新f( ),想調(diào)用基類的f則要顯式說(shuō)明y.X::f( )
6 所有構(gòu)造函數(shù)、析構(gòu)函數(shù)、operator=都不能自動(dòng)繼承
但編譯器會(huì)自動(dòng)生成默認(rèn)構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、operator=,并正確地調(diào)用基類的相應(yīng)函數(shù),它們工作的很好
自動(dòng)類型轉(zhuǎn)換函數(shù)會(huì)自動(dòng)繼承
如果想讓編譯器自動(dòng)創(chuàng)建子類的默認(rèn)構(gòu)造函數(shù),我們就不能為子類定義任何(包括拷貝)構(gòu)造函數(shù)。這和普通類的規(guī)則是一樣的
但是如果不為子類定義任何構(gòu)造函數(shù),則只能使用自動(dòng)生成的默認(rèn)和拷貝構(gòu)造函數(shù)
因此,如果想為子類定義帶參數(shù)的構(gòu)造函數(shù),則必須同時(shí)也定義子類的默認(rèn)構(gòu)造函數(shù)
如果自定義了拷貝構(gòu)造函數(shù),則也必須同時(shí)自定義默認(rèn)構(gòu)造函數(shù)
在子類的默認(rèn)構(gòu)造函數(shù)中,如果想調(diào)用基類的默認(rèn)構(gòu)造函數(shù),無(wú)需顯式調(diào)用
在子類的拷貝構(gòu)造函數(shù)中,如果想調(diào)用基類的拷貝構(gòu)造函數(shù),必須顯式在初始化列表調(diào)用,否則自動(dòng)調(diào)用默認(rèn)構(gòu)造函數(shù)
在子類的operator=中,如果想調(diào)用基類的operator=,必須顯式在函數(shù)體中調(diào)用,否則編譯器什么也不做
8 靜態(tài)成員函數(shù)的繼承規(guī)則和非靜態(tài)成員函數(shù)一樣,只是static成員函數(shù)不能是virtual
9 所以最好的方案是:
如果不定義帶參數(shù)的構(gòu)造函數(shù),就什么都不要?jiǎng)樱幾g器自動(dòng)生成符合要求的默認(rèn)/拷貝構(gòu)造、析構(gòu)、operator=
如果必須定義帶參構(gòu)造函數(shù),就要同時(shí)定義默認(rèn)構(gòu)造函數(shù),但定義時(shí)無(wú)需顯式調(diào)用基類默認(rèn)構(gòu)造函數(shù)
沒(méi)事就不要自定義拷貝構(gòu)造函數(shù)和operator=,如果一定要重定義,必須顯式調(diào)用基類的拷貝構(gòu)造函數(shù)和operator=
10 可以看到,組合類和繼承類的編譯器實(shí)現(xiàn)是一樣的
到目前為止,兩者區(qū)別在于繼承類繼承了基類的函數(shù)接口,繼承是is-a關(guān)系,組合是has-a關(guān)系
C++默認(rèn)是私有繼承,即此時(shí)并不能直接通過(guò)子類對(duì)象調(diào)用基類函數(shù)(即y.X::f()),而要在Y內(nèi)用using X::f;
11 protected的意義是僅自己和子類可以訪問(wèn)自己的成員,外部不可訪問(wèn)
private-protected-public的關(guān)系很像linux中文件權(quán)限的owner-group-others的關(guān)系
也可以protected繼承,但通常沒(méi)有應(yīng)用實(shí)例,它的存在只為語(yǔ)言的完備性
12 除operator=之外的所有基類運(yùn)算符都會(huì)自動(dòng)繼承,但它們操作的都是子類中“基類的成員”
,即,如果X和Y都有int成員i,則Y y;++y;加的是X中的i,而不是y中的i;同理operator==的意義也不會(huì)檢測(cè)y中的i
13 C++支持多重繼承,但作者認(rèn)為多重繼承總可以轉(zhuǎn)化為單重繼承,并且多重繼承很難掌握,因此不建議使用。
14 繼承和組合的優(yōu)點(diǎn)之一是支持漸進(jìn)式開(kāi)發(fā)。程序員應(yīng)當(dāng)更多關(guān)心處理數(shù)據(jù)關(guān)系,而不是進(jìn)行具體的位操作
15 子類可以自動(dòng)向上類型轉(zhuǎn)換為基類,這對(duì)于類本身、類指針、類引用都有效
在編譯器自動(dòng)生成的子類拷貝構(gòu)造函數(shù)中,首先執(zhí)行基類拷貝構(gòu)造函數(shù),之后按聲明順序執(zhí)行成員類拷貝構(gòu)造函數(shù)
多重繼承可以通過(guò)組合類的形式代替
指針和引用被自動(dòng)向上類型轉(zhuǎn)換之后,子類的成員會(huì)不能訪問(wèn),這將通過(guò)下一章的virtual函數(shù)解決
////////////////////////////////////////
Copyright @ 炮灰九段 Powered by: .Text and ASP.NET Theme by: .NET Monster