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

            ivy-jie

            progress ...

            C++博客 首頁 新隨筆 聯系 聚合 管理
              9 Posts :: 41 Stories :: 6 Comments :: 0 Trackbacks
            你不應該在構造或析構期間調用虛函數,因為這樣的調用不會如你想象那樣工作,而且它們做的事情保證會讓你很郁悶。 假設你有一套模擬股票處理的類層次結構,例如,購入流程,出售流程等。對這樣的處理來說可以核查是非常重要的,所以隨時會創建一個 Transaction 對象,將這個創建記錄在核查日志中是一個適當的要求。下面是一個看起來似乎合理的解決問題的方法:

            class Transaction { // base class for all
             public: // transactions
              Transaction();

              virtual void logTransaction() const = 0; // make type-dependent
              // log entry
              ...
            };

            Transaction::Transaction() // implementation of
            {
             // base class ctor
             ...
             logTransaction(); // as final action, log this
            } // transaction

            class BuyTransaction: public Transaction {
             // derived class
             public:
              virtual void logTransaction() const; // how to log trans-
              // actions of this type
              ...
            };

            class SellTransaction: public Transaction {
            // derived class
            public:
             virtual void logTransaction() const; // how to log trans-
             // actions of this type
            ...
            };

              考慮執行這行代碼時會發生什么:

            BuyTransaction b;

              很明顯 BuyTransaction 的構造函數會被調用,但是首先,Transaction 的構造函數必須先被調用,派生類對象中的基類部分先于派生類部分被構造。Transaction 的構造函數的最后一行調用虛函數 logTransaction,但是結果會讓你大吃一驚,被調用的 logTransaction 版本是在 Transaction 中的那個,而不是 BuyTransaction 中的——即使被創建的對象類型是 BuyTransaction。基類構造期間,虛函數從來不會向下匹配(go down)到派生類。取而代之的是,那個對象的行為就好像它的類型是基類。非正式地講,基類構造期間,虛函數禁止。 這個表面上看起來匪夷所思的行為存在一個很好的理由。因為基類的構造函數在派生類構造函數之前執行,當基類構造函數運行時,派生類數據成員還沒有被初始化。如果基類構造期間調用的虛函數向下匹配(go down)到派生類,派生類的函數理所當然會涉及到本地數據成員,但是那些數據成員還沒有被初始化。這就會為未定義行為和悔之晚矣的調試噩夢開了一張通行證。調用涉及到一個對象還沒有被初始化的部分自然是危險的,所以 C++ 告訴你此路不通。
                  在實際上還有比這更多的更深層次的原理。在派生類對象的基類構造期間,對象的類型是那個基類的。不僅虛函數會解析到基類,而且語言中用到運行時類型信息(runtime type information)的配件(例如,dynamic_cast和 typeid),也會將對象視為基類類型。在我們的例子中,當 Transaction 構造函數運行初始化 BuyTransaction 對象的基類部分時,對象的類型是 Transaction。C++ 的每一個配件將以如下眼光來看待它,并對它產生這樣的感覺:對象的 BuyTransaction 特有的部分還沒有被初始化,所以安全的對待它們的方法就是視若無睹。在派生類構造函數運行之前,一個對象不會成為一個派生類對象。

              同樣的原因也適用于析構過程。一旦派生類析構函數運行,這個對象的派生類數據成員就被視為未定義的值,所以 C++ 就將它們視為不再存在。在進入基類析構函數時,對象就成為一個基類對象,C++ 的所有配件——虛函數,dynamic_casts 等——都如此看待它。
            posted on 2009-05-18 17:26 ivy-jie 閱讀(181) 評論(0)  編輯 收藏 引用 所屬分類: c++
            国内精品伊人久久久久av一坑 | 伊人久久精品影院| 久久97精品久久久久久久不卡| 中文字幕久久亚洲一区| 久久国产高清一区二区三区| 91精品国产综合久久四虎久久无码一级| 久久久无码人妻精品无码| 伊人久久大香线焦AV综合影院| 亚洲欧洲久久久精品| 2020国产成人久久精品| 漂亮人妻被中出中文字幕久久| 亚洲精品无码久久毛片| 久久国产亚洲精品| 色综合久久夜色精品国产| 欧美国产成人久久精品| 亚洲国产另类久久久精品小说 | 久久亚洲欧美日本精品| 国产一级做a爰片久久毛片| 久久精品一区二区国产| 国产99久久九九精品无码| 久久国产乱子伦精品免费午夜| 久久久久久噜噜精品免费直播| 亚洲国产成人久久精品99 | 久久无码精品一区二区三区| 青青热久久国产久精品| 久久精品一区二区三区AV| 狼狼综合久久久久综合网| 久久久国产精品福利免费 | 中文无码久久精品| 91视频国产91久久久| 久久www免费人成精品香蕉| 亚洲精品美女久久久久99小说| 久久综合国产乱子伦精品免费| 色综合久久最新中文字幕| 欧美久久一区二区三区| 国产精品久久久香蕉| 九九99精品久久久久久| 内射无码专区久久亚洲| 精品国产一区二区三区久久久狼 | 精品久久久久久久国产潘金莲| 人妻精品久久无码区|