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

              C++博客 :: 首頁 :: 聯系 ::  :: 管理
              163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(48)

            我參與的團隊

            搜索

            •  

            積分與排名

            • 積分 - 398977
            • 排名 - 59

            最新評論

            閱讀排行榜

            評論排行榜

            設想在一個軍事應用程序里,有一個表示敵人目標的類:

            class enemytarget

            {
            public:
              enemytarget() { ++numtargets; }
              enemytarget(const enemytarget&) { ++numtargets; }
              ~enemytarget() { --numtargets; }

              static size_t numberoftargets()
              { return numtargets; }

              virtual bool destroy();         // 摧毀enemytarget對象后
                                                          // 返回成功

            private:
              static size_t numtargets;     // 對象計數器
            };

             

            //類的靜態成員要在類外定義;
            // 缺省初始化為0

            size_t enemytarget::numtargets;

            敵人的坦克是一種特殊的敵人目標,所以會很自然地想到將它抽象為一個以公有繼承方式從enemytarget派生出來的類。因為不但要關心敵人目標的總數,也要關心敵人坦克的總數,所以和基類一樣,在派生類里也采用了上面提到的同樣的技巧:

            class enemytank: public enemytarget {
            public:
              enemytank() { ++numtanks; }

              enemytank(const enemytank& rhs)
              : enemytarget(rhs)
              { ++numtanks; }

              ~enemytank() { --numtanks; }

              static size_t numberoftanks()
              { return numtanks; }

              virtual bool destroy();

            private:
              static size_t numtanks;         // 坦克對象計數器
            };

             

            最后,假設程序的其他某處用new動態創建了一個enemytank對象,然后用delete刪除掉:

            enemytarget *targetptr = new enemytank;

            ...

            delete targetptr

              這樣會發生嚴重問題,因為c++語言標準關于這個問題的闡述非常清楚:當通過基類的指針去刪除派生類的對象,而基類又沒有虛析構函數時,結果將是不可確定的。實際運行時經常發生的是,派生類的析構函數永遠不會被調用。在本例中,這意味著當targetptr 刪除時,enemytank的數量值不會改變,那么,敵人坦克的數量就是錯的。

            如果某個類不包含虛函數,那一般是表示它將不作為一個基類來使用。當一個類不準備作為基類使用時,使析構函數為虛一般是個壞主意。因為它會為類增加一個虛函數表,使得對象的體積翻倍,還有可能降低其可移植性。

            所以基本的一條是:無故的聲明虛析構函數和永遠不去聲明一樣是錯誤的。實際上,很多人這樣總結:當且僅當類里包含至少一個虛函數的時候才去聲明虛析構函數。

            抽象類是準備被用做基類的,基類必須要有一個虛析構函數,純虛函數會產生抽象類,所以方法很簡單:在想要成為抽象類的類里聲明一個純虛析構函數。

            這里是一個例子:

            class awov {                // awov = "abstract w/o
                                               // virtuals"
            public:
              virtual ~awov() = 0;      // 聲明一個純虛析構函數
            };

            這個類有一個純虛函數,所以它是抽象的,而且它有一個虛析構函數,所以不會產生析構函數問題。但這里還有一件事:必須提供純虛析構函數的定義:

            awov::~awov() {}           // 純虛析構函數的定義

            這個定義是必需的,因為虛析構函數工作的方式是:最底層的派生類的析構函數最先被調用,然后各個基類的析構函數被調用。這就是說,即使是抽象類,編譯器也要產生對~awov的調用,所以要保證為它提供函數體。如果不這么做,鏈接器就會檢測出來,最后還是得回去把它添上。

            注意:如果聲明虛析構函數為inline,將會避免調用它們時產生的開銷,但編譯器還是必然會在什么地方產生一個此函數的拷貝。

            posted on 2008-01-22 11:39 sdfasdf 閱讀(8629) 評論(4)  編輯 收藏 引用 所屬分類: C++

            Feedback

            # re: Effective C++學習筆記:確定基類有虛析構函數 2008-01-22 17:48 minidxer
            這樣寫點自己的體會并沒什么不好的,只是作者在選擇發在首頁的時候好好考慮一下就是了。
            LS的說話還是文明一些比較好  回復  更多評論
              

            # re: Effective C++學習筆記:確定基類有虛析構函數 2010-03-30 23:01 kddsly
            最底層的派生類的析構函數最先被調用,然后各個基類的析構函數被調用.
            這句話是不是說反了,不是先基類的析構被調用,然后才是派生類的被調用嗎?   回復  更多評論
              

            # re: Effective C++學習筆記:確定基類有虛析構函數 2011-01-20 10:14 SS
            奇怪啊,好像純虛函數是不能被定義的吧,為什么還可以
            awov::~awov() {} // 純虛析構函數的定義

              回復  更多評論
              

            # re: Effective C++學習筆記:確定基類有虛析構函數 2012-01-13 05:19 Jocuri online
            好的網站  回復  更多評論
              

            国产免费久久久久久无码| 久久影院亚洲一区| 久久精品九九亚洲精品| 欧美一区二区三区久久综合| 亚洲va中文字幕无码久久| 国内精品久久久久影院优| 国产福利电影一区二区三区,免费久久久久久久精 | 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 中文精品久久久久人妻不卡| 色婷婷综合久久久久中文| 日本三级久久网| 亚洲国产精品无码久久SM| 91精品国产高清久久久久久国产嫩草 | 久久亚洲国产成人精品性色| 一本大道加勒比久久综合| 狠狠色噜噜色狠狠狠综合久久 | 日韩av无码久久精品免费| 精品欧美一区二区三区久久久 | 综合久久精品色| 青青青青久久精品国产| 一本久道久久综合狠狠爱| 久久久久亚洲?V成人无码| 无码专区久久综合久中文字幕| 久久91这里精品国产2020| 亚洲伊人久久大香线蕉综合图片| 亚洲综合婷婷久久| 99久久婷婷国产综合亚洲| 久久久久久精品久久久久| 久久久噜噜噜久久中文字幕色伊伊| 国产午夜精品久久久久免费视 | 久久久久久国产精品美女| 99国产精品久久久久久久成人热| 国产精品久久久久蜜芽| 久久免费视频一区| 久久国产乱子伦精品免费午夜| 色综合久久中文综合网| 国产精品久久久久久一区二区三区 | 久久精品国产亚洲一区二区| 久久影院综合精品| 欧美午夜精品久久久久免费视| 久久久一本精品99久久精品88|