注:本文內容**於zhice163博文,感謝作者的整理。
1.為什麼基類的析構函式是虛函式?
在實現多型時,當用基類操作派生類,在析構時防止只析構基類而不析構派生類的狀況發生。
下面**網路:源位址
a.第一段**
#includeusing namespace std;class clxbase;
~clxbase() ;
void dosomething() ;
};class clxderived : public clxbase;
~clxderived() ;
void dosomething() ;
}; int main()
執行結果:
do something in class clxderived!
output from the destructor of class clxderived!
output from the destructor of class clxbase!
這段**中基類的析構函式不是虛函式,在main函式中用繼承類的指標去操作繼承類的成員,釋放指標p的過程是:先釋放繼承類的資源,再釋放基類資源.
b.第二段**
#includeusing namespace std;class clxbase;
~clxbase() ;
void dosomething() ;
};class clxderived : public clxbase;
~clxderived() ;
void dosomething()
}; int main()
輸出結果:
do something in class clxbase!
output from the destructor of class clxbase!
這段**中基類的析構函式同樣不是虛函式,不同的是在main函式中用基類的指標去操作繼承類的成員,釋放指標p的過程是:只是釋放了基類的資源,而沒有呼叫繼承類的析構函式.呼叫 dosomething()函式執行的也是基類定義的函式.
一般情況下,這樣的刪除只能夠刪除基類物件,而不能刪除子類物件,形成了刪除一半角象,造成記憶體洩漏.
在公有繼承中,基類對派生類及其物件的操作,只能影響到那些從基類繼承下來的成員.如果想要用基類對非繼承成員進行操作,則要把基類的這個函式定義為虛函式.
析構函式自然也應該如此:如果它想析構子類中的重新定義或新的成員及物件,當然也應該宣告為虛的.
c.第三段**:
#includeusing namespace std;class clxbase;
virtual ~clxbase() ;
virtual void dosomething() ;
};class clxderived : public clxbase;
~clxderived() ;
void dosomething() ;
}; int main()
執行結果:
do something in class clxderived!
output from the destructor of class clxderived!
output from the destructor of class clxbase!
這段**中基類的析構函式被定義為虛函式,在main函式中用基類的指標去操作繼承類的成員,釋放指標p的過程是:只是釋放了繼承類的資源,再呼叫基類的析構函式.呼叫dosomething()函式執行的也是繼承類定義的函式.
如果不需要基類對派生類及物件進行操作,則不能定義虛函式,因為這樣會增加記憶體開銷.當類裡面有定義虛函式的時候,編譯器會給類新增乙個虛函式表,裡面來存放虛函式指標,這樣就會增加類的儲存空間.所以,只有當乙個類被用來作為基類的時候,才把析構函式寫成虛函式.
分類:
c++好文要頂
關注我收藏該文
lizezheng
關注 - 0
粉絲 - 30
+加關注8 0
c++類中的列舉型別
發表於
2012-07-13 10:12
lizezheng 閱讀(
5) 編輯收藏
析構函式定義為虛函式原因
**先看下面一段程式:
#include
using namespace std;
class person
};class student : public person
};int main()
執行結果:
person::~person()
student::~student()
person::~person()
student::~student()
person::~person()
如果在基類中析構函式不加virtual,結果為:
person::~person()
person::~person()
student::~student()
person::~person()
可以看出:只有在用基類的指標指向派生類的時候,才會出現這種情況。因為這個時候虛函式發揮了動態的作用。
析構函式執行時先呼叫派生類的析構函式,其次才呼叫基類的析構函式。如果析構函式不是虛函式,而程式執行時又要通過基類的指標去銷毀派生類的動態物件,那麼用delete銷毀物件時,只呼叫了基類的析構函式,未呼叫派生類的析構函式。這樣會造成銷毀物件不完全。
如果在上面的例子中,基類中未定義virtual析構函式,而派生類中定義了virtual的析構函式,此時用基類指標指向派生類,再delete掉,
即:class person
};class student : public person
};person * pt = new student;
delete pt;
執行結果會出錯。
反正是只要基類析構沒有定義為virtual,而派生類(可能有多層)中有把析構定義為virtual的,此時用基類的指標指向派生類,再delete,會出錯。
而:class person
};class student : public person
};class onest : public student
};如果用
student * pt = onest;
delete pt;
執行結果為:
onest::~onest()
student::~student()
person::~person()
是可以執行的。
effective c++ (第7條:要將多型基類的析構函式宣告為虛函式)
需要記住的
分類:
c++
好文要頂
關注我收藏該文
children
關注 - 0
粉絲 - 9
+加關注0 0
c/c++程式題
c++常物件
posted @
2012-08-13 20:26
children 閱讀(
0) 編輯收藏
析構函式定義為虛函式原因
先看下面一段程式 include using namespace std class person class student public person int main 執行結果 person person student student person person student studen...
析構函式定義為虛函式原因
先看下面一段程式 include using namespace std class person class student public person int main 執行結果 person person student student person person student studen...
析構函式定義為虛函式原因
析構函式定義為虛函式原因 先看下面一段程式 include using namespace std class person class student public person int main 執行結果 person person student student person person s...