Qt的动态内存回收机制容易让人觉得困惑,而能够参考的相关资料又很少,不少都是对此一笔带过,或者给出错误的说明。费了不少劲,了解到了一些皮毛。
前言:
程序开始时,最好先把指向动态内存的指针赋值为NULL,在delete这些变量的时候,也将指针赋值为NULL 。这样,可以在程序中,通过判断是否为NULL来判断是否已经分配空间。
- 在delete过后,指针变量本身的状态是没有定义的。
- 在delete指针后立即将其赋值为NULL是经验之举。(在程序初始化(执行new之前)时,也建议将指针赋值为NULL。在new前,可以先判断指针是否为空再决定是不是new ——wulin)
- 对于一个不是由new返回的空指针实施delete操作会产生未定义的结果。
- 如果将delete操作实施与一个空指针,则不会产生任何动作也不会有错误。
1、一篇博文
http://www.cppblog.com/biao/archive/2009/07/02/89079.html
在这篇博文中,提到了Qt的窗口回收机制,复制了过来。大家也可以去原网址看。
(在程序中测试过一次,该值默认值为false,需要通过setAttribute来置为true)
又一篇博文:
/*********************************************
http://topic.csdn.net/u/20101115/19/839436ff-8e51-4e89-bd75-ab452fb2a494.html
发表于:2010-11-15 19:32:20
class MainWindow;构造函数中增加:setAttribute(Qt::WA_DeleteOnClose)以后, C/C++ code
mainWindow.setGeometry(30,30,1024,768); mainWindow.show();
C/C++ code
mainWindow->setGeometry(30, 30, 1024, 768);
mainWindow->show();
**********************************************************************************************/ |
Because this is a book on programming, you will start with some code right away (see Listing 1-1).
Listing 1-1. A simple C++ class 一个简单的C++类
#include <string>
using std::string;
class MyClass
{
public:
MyClass( const string& text );
const string& text() const;
void setText( const string& text );
int getLengthOfText() const;
private:
string m_text;
};
Let’s make this class more powerful by using Qt.
The first Qt-specific adjustment you will make to the code is really simple: you will simply let
your class inherit the QObject class, which will make it easier to manage instances of the class
dynamically by giving instances parents that are responsible for their deletion.
it is common—and recommended—to pass the parent as
an argument to the constructor as the first default argument to avoid having to type setParent
for each instance created from the class.
Listing 1-2. Inheriting QObject and accepting a parent
#include <QObject>
#include <string>
using std::string;
class MyClass : public QObject
{
public:
MyClass( const string& text, QObject *parent = 0 );
...
};
Let’s look at the effects of the change, starting with Listing 1-3 .It shows a main function
using the MyClass class dynamically without Qt.
#include <iostream>
int main( int argc, char **argv )
{
MyClass *a, *b, *c;
a = new MyClass( "foo" );
b = new MyClass( "ba-a-ar" );
c = new MyClass( "baz" );
std::cout << a->text() << " (" << a->getLengthOfText() << ")" << std::endl;
a->setText( b->text() );
std::cout << a->text() << " (" << a->getLengthOfText() << ")" << std::endl;
int result = a->getLengthOfText() - c->getLengthOfText();
delete a;
delete b;
delete c;
return result;
}
Each new call must be followed by a call to delete to avoid a memory leak. Although it is
not a big issue when exiting from the main function (because most modern operating systems
free the memory when the application exits), the destructors are not called as expected. In
locations other than loop-less main functions, a leak eventually leads to a system crash when
the system runs out of free memory. Compare it with Listing 1-4, which uses a parent that is
automatically deleted when the main function exits. The parent is responsible for calling
delete for all children and—ta-da!—the memory is freed.
■Note In the code shown in Listing 1-4, the parent object is added to show the concept. In real life, it
would be an object performing some sort of task—for example, a QApplication object, or (in the case of
a dialog box or a window) the this pointer of the window class.
#include <QtDebug>
int main( int argc, char **argv )
{
QObject parent;
MyClass *a, *b, *c;
a = new MyClass( "foo", &parent );
b = new MyClass( "ba-a-ar", &parent );
c = new MyClass( "baz", &parent );
qDebug() << QString::fromStdString(a->text())
<< " (" << a->getLengthOfText() << ")";
a->setText( b->text() );
qDebug() << QString::fromStdString(a->text())
<< " (" << a->getLengthOfText() << ")";
return a->getLengthOfText() - c->getLengthOfText();
}
It might look odd to have a parent object like this, but most Qt applications
memory situations, as shown in Figure 1-1. The parent is gray because it is allocated on the
stack and thus automatically deleted, whereas the instances of MyClass are white because they
are on the heap and must be handled manually. Because you use the parent to keep track of
the children, you trust the parent to delete them when it is being deleted. So you no longer
have to keep track of the dynamically allocated memory as long as the root object is on the
stack (or if you keep track of it).