程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++對象內存模型之虛析構函數篇(2)

c++對象內存模型之虛析構函數篇(2)

編輯:C++入門知識

c++對象內存模型之虛析構函數篇(2)


(2)有繼承關系,單一繼承,父類無虛析構函數,子類有(子類沒有就沒必要說了)   這種情況讓我相當暈,照例先貼代碼 :   復制代碼  1 #include <iostream>  2 using namespace std;  3   4 class A  5 {  6        int ia;  7        public:  8        A ():ia(15)  9      {         10       }  11      ~A () 12      { 13            cout << "~A" << endl; 14      }  15      virtual void f() 16      { 17           cout << "A:f()" <<endl; 18      }  19 }; 20  21 class B : public A 22 { 23        int ib; 24 public : 25       B():ib(31){} 26       virtual ~B() 27       { 28                  cout << "~B" << endl;            29       }   30       virtual void f() 31       { 32                  cout << "B:f()" << endl;            33       } 34         35 }; 36  37 typedef void (*F)(); 38  39 int main() 40 { 41  42      F pf = NULL; 43     B *b = new B(); 44     int **p = (int **)b; 45  46     int flag = 0; 47     pf = (F)p[0][flag]; 48     pf(); 49  50     cout << "END"<<p[0][3] << endl; 51     cout << p[1] << endl; 52     cout << p[2] << endl; 53  54     cout << sizeof(A) << endl; 55     cout << sizeof(B) << endl; 56 } 復制代碼 輸出如下:   flag = 0;     1 B:f() 2 END0 3 0xf 4 0x1f 5 8 6 12 flag = 1;   復制代碼 1 ~B 2 ~A 3 END4460356 4 0xf 5 0x1f 6 8 7 12 復制代碼 flag = 2;   復制代碼 ~B ~A END1818846781 0x2c29a0 0x1f 8 12 復制代碼  分析:   flag=0時, B的虛函數f替代了B的虛函數f,打印輸出B:f(),這個好理解。要注意的地方是,此時給flag=0,意味著,f在虛函數表的最前面,A沒有虛析構函數。END後面的數也很正常。   flag=1時,輸出為~B\n~A\n,從現象上來看,是先執行B的析構函數再執行A的析構函數,與常識相符。但END後面的數據與flag=0時的數據0不同,再加上B中的兩個成員變量的值是對的,這個讓我很難相信對象內存被釋放。如果沒有釋放,END後面的數又很難解釋。   flag=2時,輸出為~B\n~A\n,成員變量輸出已經算是亂碼,至少說明內存被釋放。ia是亂碼,ib仍然是0x1f。從輸出上來看,先後執行了B,A的析構函數,確認內存已被釋放。由於ib仍是0x1f,我認為是內存沒有更新的原因。   結論:與第一篇裡說的那樣,虛析構函數的第“二”個是釋放內存用的,第一個仍然不知道干嘛的。其它的與文章最開始介紹的兩個連接裡說的一樣,子類的虛函數會覆蓋父類對應虛函數在虛函數表中的位置。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved