2011-05-18 104 views
0

我製作了一個名爲cmysqldb的類頭文件,其中包含大量的指針。 我的問題是現在這個:C++中的析構函數

我怎麼能創建一個析構函數,將刪除可能導致潛在的內存泄漏的指針?

這裏是頭部代碼:

#ifndef CMSYQLDB_H 
#define CMSYQLDB_H 

#include <QMultiMap> 
#include <QStringList> 
#include "mysql.h" 

class cmysqldb 
{ 

public: 
    cmysqldb::~cmysqldb() 
    { 
     const char *text, 
     MYSQL *connection, 
     MYSQL_RES *result, 
     MYSQL_RES *fresult, 
     MYSQL_FIELD *mfield 
    } 
    int query_state; 
    int numfields; 
    MYSQL mysql; 
    MYSQL_ROW row; 
    MYSQL_ROW fieldrow; 


    .... 


}; 


#endif // CMSYQLDB_H 

這是你的意思???

回答

2

通過new獲取的資源應使用delete重新分配,new[]應使用delete[]重新分配。儘可能簡單,以避免內存泄漏。如果您發佈更具體的代碼,可能會更有幫助。

析構函數具有與該類相同的名稱,除了它之前有一個~符號。

cmysqldb :: ~cmysqldb() 
{ 
    // deallocate the resources with the above mentioned rule 
} 

class foo 
{ 
    int var ; 
    int *ptr ; 

    public: 

     foo() 
     { 
      ptr = new int ; 
     } 

     ~foo() 
     { 
      delete ptr ; 
     } 
}; 

void bar() 
{ 

    foo obj ; 

    // ..... 

} // <-- obj goes out of scope and it's destructor is called at this point. 

foo類有兩個成員變量分別int, int*類型的var, ptr。因此,將自動分配指定一個整數地址所需的字節,以保存指向整數地址的指針(var)和指針(ptr)。這些資源不是由我們分配的。因此,解除分配這些資源不是我們的責任。到現在爲止還挺好。

ptr = new int ; 

new int獲取從自由存儲資源,可容納一個int和它的地址返回其ptr成立。現在,從免費商店獲取資源是因爲用戶定義了new操作。所以,用戶的工作是將資源返還給免費商店。因此,在析構函數的聲明 -

delete ptr ; 

獲得從The Definitive C++ Book Guide and List一本書,甚至可以更好地解釋。還請遵循@Michael關於使用自動管理資源的智能指針的建議。

+0

另外,只有'delete'('[]')指針,你**擁有**。 – Xeo 2011-05-18 03:39:49

+0

此外,析構函數將是調用任何與MySQL相關的釋放函數的理想地方。 – 2011-05-18 03:43:03

+0

你可以給我一個樣本聲明因爲我是QT新手? – 2011-05-18 03:43:55

0

當您使用newnew[]獲取動態內存時發生內存泄漏&不使用delete或刪除[]`釋放內存。

你的構造函數聲明爲以下類型:

cmysqldb(const char *text, MYSQL *connection, MYSQL_RES *result, 
     MYSQL_RES *fresult, MYSQL_FIELD *mfield); 

你應該保持什麼動態內存分配的軌道,你與newnew[]做在構造函數中,你應該釋放所有的人都具有相應的deletedelete[]

2

爲了刪除指針,您需要將它們存儲在某個地方。目前還不清楚你在哪裏做了這些(你沒有提供構造函數接受的所有指針參數的字段),所以我不能完全給你這個代碼,但是我會展示你怎麼做到的去做這個.....

要聲明的析構函數,以下內容添加到您的類聲明:

~cmysqldb(); 

請注意,如果你的類有任何虛方法,你應該將它聲明爲:

virtual ~cmysqldb(); 

而且在你的源文件中加入:

cmysqldb::~cmysqldb() 
{ 
    // contents of your destructor goes here. 
} 

現在,你如何釋放你的資源取決於他們如何分配。如果你使用了一些庫特定的創建函數,並且有一個庫特定的免費函數,那就使用它。如果使用malloc分配,則使用free;如果它被分配了新的,請使用刪除;如果使用new []分配,則使用delete []。此外,只要有可能,您應該使用智能指針類(例如boost::scoped_ptr(std :: unique_ptr)或boost::shared_ptr(std :: shared_ptr)),以避免在構造函數/析構函數中通過new/delete顯式管理這些資源。最後一點,非常重要的一點是,只要你有一個接受指針的函數,記錄所有權語義就非常重要。它是由呼叫者擁有的嗎?所有權是否轉移?等

0

最好的辦法是使用智能指針來存儲所有指向相關對象的指針。當父對象被銷燬時,C++將自動調用所有子對象的析構函數。

如果你的父對象部分構造失敗,它的析構函數將不會被調用。因此,如果您設計要在析構函數中釋放的東西,那麼已分配的任何指針都會泄漏。但是,如果子對象被分配,子對象析構函數會運行,所以通過使用智能指針,這個部分分配的事件就會被照顧好。

欲瞭解更多信息,請查閱RAII(資源獲取初始化)。