c++对象模型-虚拟析构函数
看《inside the c++ object model》第二章,匯總一下一些知識點
( 轉自:http://www.cppblog.com/aaxron/archive/2010/12/23/137293.html)
作為通常原則,如果一個類定義了虛函數,那么它的析構函數就應該定義成虛函數。因為定義了虛函數則意味著這個類會被繼承,并且會通過基類的指針指向子類,從而得到多態。因此,基類的析構函數是否為虛函數將決定子類的對象是否被析構。
很多時候只能獲得基類的指針,但是并不知道它實際上是哪一個類,這時候刪除基類指針的時候,析構函數就很有用了,如以下代碼:
?
#include <iostream>
using namespace std;
struct A
{
A(){cout << "A::()"<<endl;}
virtual ~A() {cout<<"~A()\n";}
};
struct B: public A
{
B(){cout << "B::()"<<endl;}
~B() {cout<<"~B()\n";}
};
int main()
{
A* p = new B;
delete p;
//B b;
return 0;
}
如果A的析構函數不是virtual,那么輸出的就是~A();
如果A的析構函數是virtual,那么刪除p的時候,實際上是調用B的析構函數,因此會首先調用b的析構函數,然后再調用A的析構函數,輸出的結果是:
~B();
~A();
類如果會被派生,一般都會采用析構函數,不是防止內存泄露,而是為了正確的析構。如果是個封閉類,那么就不要定義virtual,因此虛函數的代價比較大。
不用virtual的幾種情況:
1.作為非公共基類。僅作為private base class不需要使用虛擬析構函數。
2.不作為接口使用的基類、
3.如果你可以保證這個類不被public繼承(private/protected繼承的話,在非friend函數/類中就無法用基類指針指向派生類了)?
4.如果它的所有派生類(包括派生類的派生類)的析構函數都是trivial的(這里的trivial指的是在程序員的層次什么事也不做)?
5.?如果不需要用基類的指針指向派生類的對象
?
在這五種情況下,不把析構函數聲明為virtual都是可以的,何況效率會高一些——但前提是你得保證前提的成立——不過這些保證常常是很難100%。誰能保證別人在派生你的類的時候,析構函數是trivial的,或者別人不用你提供的基類的指針指向派生類對象?這些常常是很難得到保證的。??
聲明基類的析構函數為virtual并非總是為了防止memory?? leak?? 另外這也只是作為一般的原則(基類中有虛函數則把其析構函數聲明為virtual)。如果你的析構函數什么事也不作,從效果上來說,不聲明為virtual也無妨
總結
以上是生活随笔為你收集整理的c++对象模型-虚拟析构函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ 虚拟析构函数
- 下一篇: C++:类中的赋值函数