在C++中,使用new在堆中建立的對象,需要使用delete來析構對象,進而釋放堆中的記憶體的。
在Qt中,往往new出來的對象卻不需要我們手動delete,這是因為Qt替我們做了delete這件事。
QObject *parent,有時候是QWidget *parent:
在很多時候,我們建立一個對象(無論是直接建立,還是new出來一個),都需要傳入一個“parent”指針或者手動調用setParent(*parent)函數來指定一個“父視窗”,預設的parent指針是空,此時的“父視窗”為目前的作業系統。
當指定了“父視窗”之後,該視窗的析構就由父視窗來接管,Qt會保證在合适的時候析構該視窗,并且隻析構一次。這是一個很優秀的機制。
說明:
堆對象/new出來的對象:
①QObject *parent/QWidget *parent,當指定了parent後,Qt就會介入,在合适的時候調用對應的delete操作。
②在不指定parent時,最好手動設計delete,否則這個對象的記憶體空間将交給作業系統來管理,通常在整個程式關閉以後,作業系統會回收該記憶體,一般也不會造成問題,但這畢竟是一個潛在的危險,有隐患。
棧對象:
③棧是“先入後出,後入先出”的方式,是以在建立棧對象的時候,要注意順序,舉一個例子說明:
a>出錯例子:
#include <QtGui/QApplication>
#include <QWidget>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPushButton btn;//先建立QPushButton
QWidget w;//後建立QWidget
w.show();
btn.setText("Helloworld");
btn.setParent(&w);//傳入了w作為父視窗
btn.show();
return a.exec();
}
在點選了“關閉”之後,程式崩潰了,原因是:因為btn指定了父視窗w,在關閉w時,Qt的析構機制的做法是先析構btn再析構w;在建立對象的時候,btn先建立w後建立,在棧的“先入後出,後入先出”方式下,w先出棧,btn後出棧,而此時btn已經在前面出棧了(Qt的析構機制),導緻現在程式崩潰。
b>改正後
#include <QtGui/QApplication>
#include <QWidget>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
w.show();
QPushButton btn;//将QPushButton的建立放在QWidget之後
btn.setText("Helloworld");
btn.setParent(&w);
btn.show();
return a.exec();
}
這樣做,在點選“關閉”時,便先會将btn出棧,Qt的析構機制檢測到btn已出棧,便不會再進行析構了。