• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Note of Justin

            關(guān)于工作和讀書的筆記

              C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              47 Posts :: 0 Stories :: 45 Comments :: 0 Trackbacks

            留言簿(14)

            搜索

            •  

            積分與排名

            • 積分 - 52711
            • 排名 - 433

            最新評論

            閱讀排行榜

            評論排行榜

            [原創(chuàng)文章歡迎轉(zhuǎn)載,但請保留作者信息]
            Justin 于 2010-02-23

            這次的筆記標(biāo)題比較爛,差點(diǎn)害得自己沒有心情再寫下去。
            當(dāng)然ITEM38其實(shí)也沒什么需要多記的,ITEM32中說到了“是一個”的模型,這里要回顧的是“有一個”的模型。(原文中有兩種說法,has a和implement in terms of,然而個人竊以為意思其實(shí)差不多,在筆記里就不鉆牛角尖了……)
            在“是一個”模型不適用于構(gòu)建一個類或是一種關(guān)系的時候,可以考慮“有一個”。大師給的例子應(yīng)該是被舉例舉爛了的:一個人“有一個”地址,“有一個”電話號碼,諸如此類。
            與“是一個”不同,“有一個”模型不能用公有繼承實(shí)現(xiàn),而是以類成員的方式構(gòu)造的,這個道理也很淺顯:類與其成員之間的關(guān)系本來就是“有一個”。

            到了第39條軍規(guī),講的是和私有繼承有關(guān)的事情。
            公有繼承中的子類對象是可以被轉(zhuǎn)換為它的父類對象的(“是一個”的關(guān)系),而私有繼承中這種轉(zhuǎn)換是不成立的。
            另外一點(diǎn),私有繼承中父類的所有公有和保護(hù)成員(public和protected)到了子類中,都變成了私有成員。

            因?yàn)樯厦娴奶匦裕接欣^承并不滿足“是一個”模型的需要。更可憐的是,私有繼承并不能代表一種設(shè)計思路(公有繼承代表了“是一個”的模型設(shè)計),而僅僅是“有一個”模型的一種實(shí)現(xiàn)手段(私有繼承過來的所有成員都是私有的,從這個角度來說它就只是“實(shí)現(xiàn)”)。
            另一種手段大師在Item38中有提過,就是用類成員的方式來構(gòu)造,名曰composition。
            既然兩者都能實(shí)現(xiàn)“有一個”模型,那么如何選擇呢?能用composition就用composition,必需私有繼承的時候方才私有繼承。

            比如我們有個AClass:
            class AClass{
            public:
               
            virtual void Interface_1(/*..*/);

            };

            以下為私有繼承:
            class BClass : private AClass{
            private:
               
            virtual void Interface_1(/*..*/);
            //..
            };

            而下面的composition可以達(dá)到一樣甚至更好的效果:
            class AnotherAClass: public AClass{
            public:
               
            virtual void Interface_1(/*..*/);
            //..
            };

            class DClass{
            private:
               AnotherAClass
            * a;
            //..
            };

            【以上代碼純粹是對大師例程的簡陋抄襲,大師見諒……】
            BClass和DClass都實(shí)現(xiàn)了“有一個”,但相比之下還是能分辨出長短:
            • DClass中的AnotherAClass是私有成員,除了它自己沒有人能夠訪問修改;而私有繼承的BClass不能保證其“擁有”的AClass實(shí)現(xiàn)部分不會被第三者修改,即使是私有繼承來的。(為什么這么說?看下去……)
              BClass私有繼承了AClass,相當(dāng)于它“有了一個”AClass可以用,可以玩。AClass中的公有/保護(hù)成員都變成了BClass的人,但是在享受使用這些成員的同時,BClass還要承擔(dān)提供這些成員給別人服務(wù)的義務(wù)。
              ITEM35中曾經(jīng)提到:虛擬函數(shù)機(jī)制和公有/私有/保護(hù)體制是沒有任何關(guān)系的。因此在例子中的Interface_1有可能在以下的情況中被替代然后“調(diào)用”:
              • 一個CClass公有繼承了BClass
              • CClass定義了自己的Interface_1版本
              • 有一個BClass的指針,指向一個CClass的對象,某個操作中調(diào)用了Interface_1(CClass的實(shí)現(xiàn)版本)
              這時候BClass可能要有意見了:它的作者并沒有打算讓它的繼承者修改BClass版本的Interface_1,但事實(shí)是CClass違背了它的意志!
              很曲折哈?希望我下次讀的時候還能看懂@#¥%
            • DClass由于只是定義了一個指向AnotherAClass的指針,那么在定義DClass的文件中就不需要include AClass或AnotherAClass的頭文件。于是就避免了編譯依賴(compilation dependecies)
              而BClass因?yàn)槭抢^承了AClass,在BClass的文件中就需要加上AClass的頭文件,也就不可避免的產(chǎn)生了編譯時的依賴。
            由此看來,絕大部分情況下,組合方式(composition)是要優(yōu)于私有繼承的。之所以說“絕大部分”,是因?yàn)榇髱熣f了:
            對于EBO(Empty Base Optimization)的情況,私有繼承就顯現(xiàn)出了它的優(yōu)勢。
            所謂EBO就是這樣的一種情況,有一種特殊的類,它沒有非靜態(tài)數(shù)據(jù)成員(non-static data member),也沒有虛函數(shù)(于是不會需要空間存儲虛表)。
            所以這樣的一種類其實(shí)不占用任何空間,不過因?yàn)镃++不允許0字節(jié)的對象存在,而且很多編譯器都會添加額外的空間來實(shí)現(xiàn)字節(jié)對齊,于是這種特殊的類的實(shí)際大小應(yīng)該是1個char對象的大小。
            在這種類中,往往會有很多typedef,enum,靜態(tài)數(shù)據(jù)成員或者是非虛函數(shù)。所以他們還是有價值的。
            需要在“有一個”關(guān)系中利用這種類的時候,如果采用composition,那么根據(jù)上面的結(jié)論,就需要付出額外的空間來“存放”這個本來不占空間的類。
            然而如果是私有繼承呢,就可以避免這種情況。
            (最后是我的想法:這么精打細(xì)算……現(xiàn)在貌似很少人會用到這個EBO了吧?如果真的需要,就再回到原書中看看例子吧。)

            posted on 2010-03-08 09:15 Justin.H 閱讀(305) 評論(0)  編輯 收藏 引用 所屬分類: Effective C++ 炒冷飯
            久久精品亚洲精品国产欧美| 久久国产免费观看精品3| 欧美精品一区二区久久| 久久综合精品国产一区二区三区| 人妻无码精品久久亚瑟影视| 中文字幕日本人妻久久久免费| 久久91亚洲人成电影网站| 久久久久这里只有精品 | 欧美精品一区二区精品久久| 开心久久婷婷综合中文字幕| 久久天天躁狠狠躁夜夜网站 | 久久久久久国产a免费观看黄色大片 | 久久久这里有精品中文字幕| 色欲综合久久中文字幕网| 久久久久婷婷| 国产精品岛国久久久久| 久久久久人妻一区二区三区| 免费国产99久久久香蕉| 天天爽天天狠久久久综合麻豆| 国产精品成人99久久久久91gav| 亚洲愉拍99热成人精品热久久| 婷婷久久综合九色综合九七| 久久精品国产亚洲综合色| 伊人久久大香线蕉av不卡| 色8激情欧美成人久久综合电| 国产精品午夜久久| 国産精品久久久久久久| 国产婷婷成人久久Av免费高清| 亚洲愉拍99热成人精品热久久| 国产精品久久新婚兰兰| 精品国产日韩久久亚洲 | 精品国产乱码久久久久久郑州公司 | 久久精品一本到99热免费| 久久无码AV一区二区三区| 人妻中文久久久久| 久久久久久久免费视频| 国内精品伊人久久久影院 | 久久久噜噜噜久久| 久久久久国产一区二区| 久久人妻少妇嫩草AV蜜桃| 久久精品国产欧美日韩|