• <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++
            精品国产日韩久久亚洲| 久久伊人五月天论坛| 人妻无码中文久久久久专区| 亚洲欧美日韩精品久久亚洲区 | 久久精品国产只有精品66 | A级毛片无码久久精品免费 | 亚洲精品国产综合久久一线| 久久伊人精品一区二区三区| 97久久综合精品久久久综合| 精品久久久久久久中文字幕 | 久久精品一区二区三区中文字幕| 欧美性猛交xxxx免费看久久久| 亚洲成色WWW久久网站| 久久久久久久综合日本亚洲| 久久99热这里只频精品6| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 国产美女久久精品香蕉69| 国产午夜电影久久| 精品综合久久久久久888蜜芽| 精品多毛少妇人妻AV免费久久| 少妇高潮惨叫久久久久久| 色悠久久久久久久综合网| 色综合色天天久久婷婷基地| 日韩精品久久久久久久电影蜜臀| 久久国产高清一区二区三区| 久久精品国产99久久久 | 精品国产一区二区三区久久| 狠狠色丁香婷婷久久综合五月| 狠狠色丁香婷婷综合久久来来去| 精品无码久久久久久尤物| 久久精品国产亚洲av麻豆图片| 国产精品免费久久久久影院| 久久综合九色综合欧美狠狠| jizzjizz国产精品久久| 久久人人爽人人爽人人AV| 久久久久青草线蕉综合超碰| 久久精品中文字幕大胸| 久久天天躁夜夜躁狠狠躁2022| 午夜福利91久久福利| 欧美午夜精品久久久久久浪潮| 婷婷久久综合九色综合九七|