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

            我參與的團隊

            搜索

            •  

            積分與排名

            • 積分 - 400062
            • 排名 - 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 閱讀(8634) 評論(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
            好的網站  回復  更多評論
              

            777午夜精品久久av蜜臀| 久久永久免费人妻精品下载| 伊人久久大香线焦综合四虎| 一本大道久久a久久精品综合| 国内精品欧美久久精品| 2021国内久久精品| 99久久国产精品免费一区二区| 国产午夜精品久久久久免费视| 久久久久香蕉视频| 亚洲午夜久久久久久噜噜噜| A级毛片无码久久精品免费| 99久久免费国产精品特黄| 青青青青久久精品国产h| 香蕉久久夜色精品国产2020| 91精品国产91久久综合| 欧美日韩久久中文字幕| 国产成人精品久久| 久久精品国产亚洲av高清漫画| 亚洲国产成人久久一区久久 | 精品999久久久久久中文字幕| 久久久中文字幕日本| 久久99精品国产麻豆| 久久人人爽人人爽人人爽| 99久久精品无码一区二区毛片| 蜜臀av性久久久久蜜臀aⅴ麻豆| 伊人久久亚洲综合影院| 久久精品夜色噜噜亚洲A∨| 色偷偷888欧美精品久久久| 久久91精品久久91综合| 日韩久久久久久中文人妻| 亚洲狠狠婷婷综合久久久久| 亚洲精品国产综合久久一线| 久久精品国产精品亚洲艾草网美妙| 99久久免费国产精精品| 国内精品久久久久伊人av| 久久狠狠高潮亚洲精品| 久久精品亚洲一区二区三区浴池| 久久亚洲AV成人无码国产| 国产精品久久久久9999| 狠狠色噜噜狠狠狠狠狠色综合久久 | 国产91色综合久久免费|