so true

          心懷未來,開創(chuàng)未來!
          隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
          數(shù)據(jù)加載中……

          基類的析構(gòu)函數(shù)為什么要設(shè)成虛函數(shù)

          #include <iostream.h>

          class A
          {
          public:
           A(){cout<<"A()\n";}
           ~A(){cout<<"~A()\n";}
           
          };

          class B : public A
          {
          public:
           B(){cout<<"B()\n";}
           ~B(){cout<<"~B()\n";}
          };

          void main()
          {
           A * p = new B();
           delete p ;  
          }
          輸出結(jié)果:
          A()
          B()
          ~A()
          ============================================================
          在基類的析構(gòu)函數(shù)前添加virtual改編后的代碼:
          #include <iostream.h>

          class A
          {
          public:
           A(){cout<<"A()\n";}
           virtual ~A(){cout<<"~A()\n";}
           
          };

          class B : public A
          {
          public:
           B(){cout<<"B()\n";}
           ~B(){cout<<"~B()\n";}
          };

          void main()
          {
           A * p = new B();
           delete p ;  
          }

          輸出結(jié)果:
          A()
          B()
          ~B()
          ~A()
          =================================================================
          如果不是在基類的析構(gòu)函數(shù)前添加virtual,而是在子類的析構(gòu)函數(shù)前添加virtual,則編譯不會出錯,但是運行會出錯。如果在此基礎(chǔ)上再把“delete p;”這句話給注釋了,那依然不會運行出錯,不過這就不符合變成規(guī)范了,只要是我們自己用new創(chuàng)建的東西,我們就必須在適當(dāng)?shù)奈恢蔑@示的調(diào)用delete來刪除。
          =================================================================
          如果再添加一個中間類,代碼如下:
          #include <iostream.h>
          #include <windows.h>

          class A
          {
          public:
           A(){cout<<"A()\n";}
           virtual ~A(){cout<<"~A()\n";}
          };

          class B : public A
          {
          public:
           B(){cout<<"B()\n";}
           virtual ~B(){cout<<"~B()\n";}
          };

          class C : public B
          {
          public:
           C(){cout<<"C()\n";}
           ~C(){cout<<"~C()\n";}
          };

          void main()
          {
           A * p = new C();
           delete p ;  
          }
          輸出結(jié)果為:
          A()
          B()
          C()
          ~C()
          ~B()
          ~A()
          析構(gòu)函數(shù)前添加virtual,必須要在最最根上的基類的析構(gòu)函數(shù)前添加,不能再B類或C類的析構(gòu)函數(shù)前添加,只要A類的析構(gòu)函數(shù)添加了virtual,從A類派生的類都不必在自己的析構(gòu)函數(shù)前添加virtual了。
          所以如果沒有虛析構(gòu)函數(shù)的話, 那么子類中特有的部分就不會被釋放, 造成"經(jīng)典"的釋放一半, 泄露一半的內(nèi)存泄露.

          posted on 2008-02-23 19:17 so true 閱讀(1784) 評論(0)  編輯  收藏 所屬分類: C&C++

          主站蜘蛛池模板: 黄石市| 龙岩市| 临夏市| 潼南县| 抚松县| 思南县| 司法| 永嘉县| 诏安县| 九江市| 乳山市| 盘锦市| 平乡县| 新巴尔虎左旗| 台中市| 横山县| 江津市| 永康市| 阜平县| 元阳县| 东丰县| 庆阳市| 仙桃市| 磴口县| 平顶山市| 澜沧| 龙游县| 荣成市| 海口市| 辽阳县| 祁门县| 桑植县| 镇原县| 延川县| 教育| 楚雄市| 九龙县| 济源市| 东丰县| 佳木斯市| 牙克石市|