基類指標或引用可以指向或是引用派生類物件,下文以指標為例作講解。引用的例子類似,不再贅述。
如果基類指標向派生類物件,則刪除此指標時,我們希望呼叫該指標指向的派生類析構函式,而派生類的析構函式又自動呼叫基類的析構函式,這樣整個派生類的物件完全被釋放。
若使用基類指標操作派生類,需要防止在析構時,只析構基類,而不析構派生類。
但是,如果析構函式不被宣告成虛函式,則編譯器採用的繫結方式是靜態繫結,在刪除基類指標時,只會呼叫基類析構函式,而不呼叫派生類析構函式,這樣就會導致基類指標指向的派生類物件析構不完全。若是將析構函式宣告為虛函式,則可以解決此問題。
比較以下三個例子:
1、第一段**
#includeusing namespace std;
class bc;
~bc() ;
void fun1() ;
private:
string * strsbc;
};class dc : public bc;
~dc () ;
void fun1() ;
private:
int *pa;
};int main()
執行結果:
bc::bc()!
dc::dc()!
dc::fun1()!
free pa in dc::~dc()!
free strsbc in bc::~bc()!
這段**中,基類析構函式不是虛函式。在main函式中,用子類指標操作子類。釋放指標p的過程是:先釋放繼承類的資源,再釋放基類資源,則釋放是完全的,不存在問題。
2、第二段**
#includeusing namespace std;
class bc;
~bc() ;
void fun1() ;
private:
string * strsbc;
};class dc : public bc;
~dc () ;
void fun1() ;
private:
int *pa;
};int main()
輸出結果:
bc::bc()!
dc::dc()!
bc::fun1()!
free strsbc in bc::~bc()!
這段**中,基類析構函式不是虛函式,但在main函式中,用基類指標操作子類,釋放指標p的過程是:只是釋放了基類申請的資源,而沒有呼叫子類的析構函式,沒有釋放了子類申請的資源。呼叫fun1()函式,執行的也是基類定義的函式。
一般情況下,這樣的刪除只能夠刪除基類物件,而不能刪除子類物件,形成了刪除一半角象,造成記憶體洩漏。
要想解決上述問題,需要宣告析構函式是虛函式。
3、第三段**:
#includeusing namespace std;
class bc;
virtual ~bc() ;
virtual void fun1() ;
private:
string * strsbc;
};class dc : public bc;
~dc () ;
void fun1() ;
private:
int *pa;
};int main()
執行結果:
bc::bc()!
dc::dc()!
dc::fun1()!
free pa in dc::~dc()!
free strsbc in bc::~bc()!
這段**中,基類析構函式是虛函式。在main函式中,用基類指標操作子類,釋放指標p的過程是:先釋放子類申請的資源,再呼叫基類析構函式,釋放父類申請的資源。呼叫fun1()函式,執行的也是子類中定的函式,表現出了多型特徵。
C 析構函式為什麼要為虛函式
1.為什麼基類的析構函式是虛函式?在實現多型時,當用基類操作派生類,在析構時防止只析構基類而不析構派生類的狀況發生。下面 網路 源位址 a.第一段 includeusing namespace std class clxbase clxbase void dosomething class clxd...
C 析構函式為什麼要為虛函式
注 本文內容 於zhice163博文,感謝作者的整理。1.為什麼基類的析構函式是虛函式?在實現多型時,當用基類操作派生類,在析構時防止只析構基類而不析構派生類的狀況發生。下面 網路 源位址 a.第一段 includeusing namespace std class clxbase clxbase ...
C 析構函式為什麼要為虛函式
在實現多型時,當用基類操作派生類,在析構時防止只析構基類而不析構派生類的狀況發生。a.第一段 includeusing namespace std class clxbase clxbase void dosomething class clxderived public clxbase clxde...