C++中的析构函数

Destructor in C++

本文关键字:析构函数 C++      更新时间:2023-10-16

我用一个名为cmysqldb的类制作了一个头文件,有很多指针。我现在的问题是:

如何创建一个析构函数来删除可能导致潜在内存泄漏的指针?

这是标头代码:

#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

这是你的意思吗???

通过new获得的资源应使用deletenew[] 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类有两个成员变量,分别var, ptr类型为 int, int*。因此,在 var 和指针 ( ptr ) 中保存整数所需的字节会自动分配,该指针可以指向整数的地址。这些资源不是由我们分配的。因此,解除这些资源不是我们的责任。目前为止,一切都好。

ptr = new int ;

new int从可以保存int的免费存储中获取资源,并返回其地址,ptr保存。现在,这种从免费商店获取资源是因为用户定义的new操作。因此,用户的工作是将资源返回到免费商店。所以,析构函数中的语句——

delete ptr ;

从权威C++书指南和列表中获取一本书,甚至可以更好地解释。还要遵循使用智能指针@Michael建议,自动管理资源。

为了删除指针,您需要将它们存储在某个地方。目前还不清楚你在哪里这样做(你没有构造函数接受的所有指针参数的字段),所以我无法准确地给你这样做的代码,但我会列出你如何去做这件事.....

若要声明析构函数,请将以下内容添加到类声明中:

~cmysqldb();

请注意,如果您的类将具有任何虚拟方法,则应将其声明为:

virtual ~cmysqldb();

并在源文件中添加:

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

现在,如何释放资源取决于资源的分配方式。如果您使用了一些特定于库的创建函数,并且有一个特定于库的免费函数,请使用该函数。如果它是使用 malloc 分配的,则使用 free;如果分配了 new,请使用删除;如果它是使用 new[] 分配的,则使用 delete[]。此外,应尽可能使用 boost::scoped_ptr (std::unique_ptr) 或 boost::shared_ptr (std::shared_ptr) 等智能指针类,以避免通过构造函数/析构函数中的 new/delete 显式管理这些资源。

最后,非常重要的一点...每当有一个接受指针的函数时,记录所有权语义非常重要。它是否归调用方所有?所有权是否转移?等。

当您使用 newnew[] 获取动态内存并且不使用 delete 或 delete[]' 释放内存时,会发生内存泄漏。

构造函数声明的类型为:

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

您应该使用 newnew[] 跟踪您在构造函数中执行的任何动态内存分配,并且您应该使用相应的 deletedelete[] 来释放所有这些内存分配。

最好的办法是使用智能指针来存储指向相关对象的所有指针。 C++ 将在销毁父对象时自动调用所有子对象的析构函数。

如果父对象部分构造失败,则不会调用其析构函数。 因此,如果您设计要在析构函数中释放的内容,则任何已分配的指针都会泄漏。 但是,如果分配了子对象,则子对象析构函数将运行,因此通过使用智能指针,可以为您处理此部分分配的情况。

有关详细信息,请查找 RAII(资源获取正在初始化)。