C++中的析构函数
Destructor in C++
我用一个名为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
获得的资源应使用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
类有两个成员变量,分别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 显式管理这些资源。
最后,非常重要的一点...每当有一个接受指针的函数时,记录所有权语义非常重要。它是否归调用方所有?所有权是否转移?等。
当您使用 new
或 new[]
获取动态内存并且不使用 delete
或 delete[]' 释放内存时,会发生内存泄漏。
构造函数声明的类型为:
cmysqldb(const char *text, MYSQL *connection, MYSQL_RES *result,
MYSQL_RES *fresult, MYSQL_FIELD *mfield);
您应该使用 new
和 new[]
跟踪您在构造函数中执行的任何动态内存分配,并且您应该使用相应的 delete
或 delete[]
来释放所有这些内存分配。
最好的办法是使用智能指针来存储指向相关对象的所有指针。 C++ 将在销毁父对象时自动调用所有子对象的析构函数。
如果父对象部分构造失败,则不会调用其析构函数。 因此,如果您设计要在析构函数中释放的内容,则任何已分配的指针都会泄漏。 但是,如果分配了子对象,则子对象析构函数将运行,因此通过使用智能指针,可以为您处理此部分分配的情况。
有关详细信息,请查找 RAII(资源获取正在初始化)。
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- 不命名构造函数和析构函数上的类型错误