• <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
            好的網站  回復  更多評論
              

            久久国产精品99精品国产| 国内精品久久久久影院亚洲| 777午夜精品久久av蜜臀| 久久99精品国产麻豆宅宅| 久久精品国产亚洲AV蜜臀色欲| 亚洲精品无码久久千人斩| 亚洲国产精品一区二区久久| 日本亚洲色大成网站WWW久久| 亚洲中文字幕无码一久久区| 欧美精品一本久久男人的天堂| 怡红院日本一道日本久久| 亚洲午夜无码久久久久小说 | 久久久精品午夜免费不卡| 久久久久这里只有精品| av色综合久久天堂av色综合在 | 久久亚洲美女精品国产精品| 91久久精品国产成人久久| 亚洲av伊人久久综合密臀性色| 91精品日韩人妻无码久久不卡 | 久久九九久精品国产| 一本一本久久aa综合精品| 久久久久亚洲AV成人网人人网站 | 亚洲欧美日韩精品久久亚洲区| 国内精品久久久久影院日本| 久久夜色精品国产亚洲| 久久天天躁狠狠躁夜夜av浪潮| 91麻豆精品国产91久久久久久| 久久精品国产亚洲AV麻豆网站| 无码人妻久久一区二区三区免费丨 | 欧美一级久久久久久久大片| 午夜福利91久久福利| 91麻精品国产91久久久久 | 久久综合综合久久综合| 伊人久久大香线蕉AV一区二区| 国内精品久久久久久麻豆| 91久久香蕉国产熟女线看| 9191精品国产免费久久| 99久久亚洲综合精品成人| 国产香蕉97碰碰久久人人| 久久se精品一区二区影院| 国产农村妇女毛片精品久久|