先來看一段代碼
#include <iostream>
using namespace std;
class A
{
public:
A(){
cout << "A() ...." << endl;
}
~A()
{
cout << "~A()...." << endl;
}
void func()
{
cout << "a --> func()...." << endl;
}
};
class MyAutoPtr //定義一個指向A類的智能指針
{
public:
MyAutoPtr(void* ptr) //ptr = new A;
{
this->m_p = ptr;
}
~MyAutoPtr()
{
if (this->m_p != NULL) {
cout << "delete m_p" << endl;//打印信息,表示已運行MyAutoPtr類的析構函數
delete m_p;
}
}
private:
void* m_p;//指向A對象的地址。
};
void test()
{
MyAutoPtr auto_p(new A); //創建一個對象,並在test函數結束時銷毀
}
int main(void)
{
test();
return 0;
}
輸出結果如下
A() ....
delete m_p
這段代碼中MyAutoPtr類中有一個void類指針m_p指向類A,最后在對象auto_p銷毀時調用MyAutoPtr類中析構函數釋放掉m_p指向的內存即類A,按理來說是會調用類A的析構函數進行進一步的釋放,但是輸出結果表示系統只運行到了MyAutoPtr類中的析構函數,並未調用類A的析構函數,這就造成了類A的內存並未被釋放。
若將MyAutoPtr類中的指針m_p改為A類型,再次運行就顯示正確的調用了類A的析構函數。
由此可知,若一個void類型指針指向了一個類,那么系統在釋放這個指針時並不會調用該類中的析構函數去釋放內存,會造成內存泄漏。這也是為什么C++中模板類大多需要調用者在調用時顯式標注數據類型的原因。
————————————————