• <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>

            deepway

              C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              1 Posts :: 9 Stories :: 1 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(4)

            我參與的團隊

            搜索

            •  

            最新評論

            • 1.?re: 軟件運行日志[未登錄]
            • 我覺得調試日志不應該只記錄軟件的非正常過程吧,而是記錄軟件的運行過程。期間有不正常的時候用warning,error和fetal來記錄。
            • --hi


            問題描述:
               在 C++ 面向對象編程中,常常會遇到“類型識別”的需求:已知某個對象的基類型指針,需要識別該對象的派生類型,訪問派生類型的公有函數。簡單說就是,將基類型指針轉換為派生類型指針,并用來訪問派生類型的公有函數。

            問題分析: 
               “類型識別”本質上是一個從抽象轉為具象的過程,破壞了對象抽象性。雖不值得提倡,但在具象化情景下,“類型識別”又是必須的。
               “類型識別”常規方法是強制類型轉換。這需要先定義一個“對象類型”枚舉表,再在基類里定義一個返回“對象類型”的函數。這種方法的缺點顯而易見:
                     1. 需要維護全局性的“對象類型”枚舉表;
                     2. 向基類型構造函數傳入“對象類型”參數;
                     3. 每次“類型轉換”前,先要獲得“對象類型”值,判斷對象類型;
               “類型識別”的另一種標準方法是RTTI。作為一項 C++ 編譯選項,RTTI 直接將上述常規方法教給編譯器做了。然而,這樣也是有缺點的:
                     1. RTTI會引入額外的開銷。這是可以理解的,問題是RTTI這種開銷會附加到所有類型上去;
                     2. RTTI要求所有庫都以RTTI方式編譯,才能正常工作。而現實世界總是復雜的,這一點未必總是能實現;
                     3. 個人認為RTTI是一種過于形式化的東西,違反了 C++ 的簡潔性、高效性原則;
                     4. 個人認為RTTI的低層形式化的東西,很多時候,我們仍然需要定義不依賴于C++類的“對象類型”枚舉表;
               閱讀 WebKit 代碼時,我看到了一種基于虛函數的“類型識別”方法,代碼如下:
               class EventTarget {
               public:
                    void ref() { refEventTarget(); }
                    void deref() { derefEventTarget(); }

                    virtual EventSource* toEventSource();
                    virtual MessagePort* toMessagePort();
                    virtual Node* toNode();
                    virtual DOMWindow* toDOMWindow();
                    virtual XMLHttpRequest* toXMLHttpRequest();
                    virtual XMLHttpRequestUpload* toXMLHttpRequestUpload();

             在基類中,定義向派生類型的轉換函數,并且返回為NULL。每個派生類型,重新實現向自身轉換的轉換函數,返回自身的指針。我感覺這種方法:
                     1. 非常安全,使用方便;
                     2. 效率相對比較高;
                     3. 省卻了全局性的“對象類型”枚舉表,卻帶來了維護基類“轉換函數”的負擔;
                     4. 造成了基類對派生類的依賴性,似乎不太好。

               在上述方法的基礎上,設想了一種改進的方法,設計原則是“從基類型向派生類型轉換的函數,應該放置在派生類中,以靜態函數的方式定義”。具體方法如下:
                     1. 基類定義 void* toXXXX() 和 bool isXXXX() 兩個私有虛函數,用編程規范規定,禁止派生類直接訪問它們。
                     2. 派生類重定義上述函數。
                     3. 派生類型定義 XXXX* toType(Base*) 和 bool isType(Base*)兩個靜態函數,內部實現就是通過上述私有虛函數完成的。
                     4. 所有的“類型識別操作”都使用上述靜態函數完成。

            問題小結:
                     上述四種方式,很難說哪一種方式更好,宜具體情況具體對待。
                      我本人偏向于,使用最后一種方式作為C++編程規范和模式,因為,它更是一種接口規范,其內部實現可以改為前三種方法中的任何一種。至于它帶來的些許工作量,我認為,在它成為一種工作規范后,那些少量代碼僅僅只是一點點沒有難度的機械性編程,完全可以忽略不計。如果不介意在代碼中使用宏機制,那么更可以用宏來實現,那么只需定義編譯宏就能就在三種方式之間任意切換。
                     最后一種方式,體現了一種策略:當你想為基類定義一些與派生類相關的工具函數時,倒不如將其定義為派生類的靜態函數,以避免派生類型對基類型的“污染”。

            posted on 2010-06-28 20:21 maxime 閱讀(623) 評論(0)  編輯 收藏 引用 所屬分類: C++ 設計模式
            国产成人精品久久一区二区三区av| 久久国产劲爆AV内射—百度| 94久久国产乱子伦精品免费| 伊人久久大香线蕉综合网站| 久久精品国产久精国产| 久久人与动人物a级毛片| 久久久噜噜噜久久熟女AA片| 国产精品久久新婚兰兰| 久久精品这里只有精99品| avtt天堂网久久精品| 久久精品无码午夜福利理论片| 久久综合狠狠色综合伊人| 精品久久一区二区三区| 亚洲日韩欧美一区久久久久我| 狠狠88综合久久久久综合网| 久久人搡人人玩人妻精品首页| 久久乐国产精品亚洲综合| 久久午夜伦鲁片免费无码| 99久久精品午夜一区二区| 亚洲欧美另类日本久久国产真实乱对白 | 狠狠色丁香久久婷婷综合图片| 国产精品久久久久天天影视| 国产精品久久久久久一区二区三区 | 77777亚洲午夜久久多喷| 久久人人爽人人爽人人片AV麻烦 | 国产韩国精品一区二区三区久久| 久久久国产视频| 一本久久a久久精品亚洲| 久久久免费精品re6| 97精品伊人久久久大香线蕉 | 久久这里只有精品首页| 性做久久久久久久久老女人| 午夜精品久久影院蜜桃| 国内精品伊人久久久久网站| 亚洲国产成人精品久久久国产成人一区二区三区综| 囯产极品美女高潮无套久久久| 亚洲国产精品综合久久一线| 久久婷婷色香五月综合激情| 久久久久18| 欧美精品九九99久久在观看| 伊人久久大香线蕉综合5g|