在 Qt之QTextCodec乱谈 一文中我们提到这个一样例子
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTextCodec * codec = new DbzhangCodec;
QTextCodec::setCodecForCStrings(codec);
qDebug()<<QString("hello world!");
return 0;
}
其中,DbzhangCodec是QTextCodec的一个派生类。这儿使用了 new ,但是却没有相应地使用 delete,可是却没有造成内存泄漏,原因何在?
构造与析构函数
从构造函数开始看起:当对象被创建时,它会将指向自己的指针添加到一个static的列表中。
/*!
Constructs a QTextCodec, and gives it the highest precedence. The
QTextCodec should always be constructed on the heap (i.e. with \c
new). Qt takes ownership and will delete it when the application
terminates.
*/
QTextCodec::QTextCodec()
{
...
all->prepend(this);
}
其中:all是一个static的列表
static QList<QTextCodec*> *all = 0;
看一下析构函数
/*!
Destroys the QTextCodec. Note that you should not delete codecs
yourself: once created they become Qt's responsibility.
*/
QTextCodec::~QTextCodec()
{
if (all) {
all->removeAll(this);
...
}
}
上面的两段注释明确告诉我们:对象必须分配在heap中,而且由Qt负责在程序退出之前删除它。
可是,删除操作是怎么实现的呢?
QTextCodecCleanup
class QTextCodecCleanup
{
public:
~QTextCodecCleanup();
};
/*
Deletes all the created codecs. This destructor is called just
before exiting to delete any QTextCodec objects that may be lying
around.
*/
QTextCodecCleanup::~QTextCodecCleanup()
{
...
for (QList<QTextCodec *>::const_iterator it = all->constBegin()
; it != all->constEnd(); ++it) {
delete *it;
}
delete all;
all = 0;
...
}
这是一个很简单的类,只定义了一个析构函数:负责删除列表 all 中的所有QTextCodec对象。
要使得这个析构函数被调用,显然需要构造一个QTextCodecCleanup对象,这是通过:
Q_GLOBAL_STATIC(QTextCodecCleanup, createQTextCodecCleanup)
实现的
Q_GLOBAL_STATIC
这个宏定义在 qglobal.h 这个头文件内(根据你所用的Qt的版本不同,你的源码初看起来与此可能有很大不同)。
#define Q_GLOBAL_STATIC(TYPE, NAME) \
static TYPE *NAME() \
{ \
static QGlobalStatic<TYPE > thisGlobalStatic \
= { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \
if (!thisGlobalStatic.pointer && !thisGlobalStatic.destroyed) { \
TYPE *x = new TYPE; \
if (!thisGlobalStatic.pointer.testAndSetOrdered(0, x)) \
delete x; \
else \
static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \
} \
return thisGlobalStatic.pointer; \
}
由于考虑了线程安全性,这个宏看起来还真乱,其实呢,也就是一个静态的函数
static QTextCodecCleanup * createQTextCodecCleanup()
{
}
该函数内,创建了两个静态的对象
static QGlobalStatic<QTextCodecCleanup> thisGlobalStatic; static QGlobalStaticDeleter<QTextCodecCleanup> cleanup(thisGlobalStatic);
thisGlobalStatic 中保存有 QTextCodecCleanup 对象的指针(并作为函数的返回值返回);cleanup 析构时将析构掉该指针所指向的对象。
Qt中QTextCodec内存管理

探讨了Qt中QTextCodec类如何管理内存,避免内存泄漏。文章详细解析了QTextCodec的构造与析构过程,并介绍了QTextCodecCleanup类的作用。
3987

被折叠的 条评论
为什么被折叠?



