qt中new与delete使用示例
qt中有時候使用new后并沒有使用delete,原因是
Qt?自動回收是靠父子關系。父親銷毀了。他的孩子也銷毀。
delete(Qobject* obj)//有時需要手動銷毀
delete(this); //delete this;#include "mainwindow.h"
#include <QApplication>
#include <QTextCodec>
#include <QLabel>
int main(int argc, char *argv[])
{
? ? QApplication a(argc, argv);
? ? MainWindow w;
? ? QLabel *label =new QLabel("hello",&w);
? ? //這里使用new之后不需要執行delete,因為label的父類是w,而w是在棧中創建,在程序關閉的時候會自動釋放,所以作為w的子類內存也被釋放。
? ? QLabel *label1 =new QLabel("world");
? ? //這個是需要執行delete label1,否則會造成內存泄漏,因為label沒有父類,所以不會為label釋放內存
? ? w.show();
? ? a.exec();
? ? delete label1;
? ? label1=NULL;
? ? return 0;
}
?
總的來說,Qt的對象如果使用new聲明為指針,那么:(1)如果它沒有父對象,
可以在不需要的使用使用delete把它釋放。(2)如果它有父對象,會在父對象
銷毀的時候同時被銷毀。父對象什么時候銷毀參見第一條。下面是一些例子。
1、使用delete
這個例子如下
//第一個程序
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
? ? QApplication app(argc, argv);
? ? QLabel *label = new QLabel;
? ? label->setFrameStyle(QFrame::Panel | QFrame::Sunken);
? ? label->setText("first line\nsecond line");
? ? label->setAlignment(Qt::AlignBottom | Qt::AlignRight);
? ? label->show();
? ??
? ? return app.exec();
}
//第二個程序
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
? ? QApplication app(argc, argv);
? ? QLabel *label = new QLabel;
? ? label->setFrameStyle(QFrame::Panel | QFrame::Sunken);
? ? label->setText("first line\nsecond line");
? ? label->setAlignment(Qt::AlignBottom | Qt::AlignRight);
? ? label->show();
? ? int ret = app.exec();
? ? //釋放內存
? ? delete label;
? ??
? ? return ret;
}
因為label沒有父對象,所以它的釋放只能自己來。第一個程序沒有釋放內存。
第二個程序使用了delete釋放了內存。
2、使用標志位
使用標志位可以不顯示的使用delete,但和使用delete是一樣的。因為Qt在暗中
使用了delete。
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
? ? QApplication app(argc, argv);
? ? QLabel *label = new QLabel;
? ? label->setAttribute(Qt::WA_DeleteOnClose);
? ? label->setText("first line\nsecond line");
? ? label->show();
? ??
? ? return app.exec();
}
下面是一個暗中使用delete的例子。這是一個類,它有一個成員函數,可以刪除
自己。當然只能刪除由關鍵字new創建的自己。
#include<iostream>
using namespace std;
//類AAA
class AAA
{
public:
? ? //構造函數
? ? AAA();
? ? ~AAA(void);
? ? void delete_me(void);
};
//構造函數
AAA::AAA(void)
{
? ? //空的
}
//析構函數
AAA::~AAA(void)
{
? ? //空的
}
//刪除自己
void AAA::delete_me(void)
{
? ? delete this;
}
?
?
?
//主函數
int main(void)
{
? ? AAA *a = new AAA;
? ? cout<<"point a will be deleted by himself."<<endl;
? ? a->delete_me();
? ? cout<<"point a has been deleted."<<endl;
? ??
? ? return 0;
}
3、依靠父對象
下面是第二種情況。例子如下
#include <QApplication>
#include <QWidget>
#include <QPushButton>
//自定義類
class MyWidget : public QWidget
{
public:
? ? MyWidget(QWidget *parent = 0);
? ? ~MyWidget();
};
//構造函數
MyWidget::MyWidget(QWidget *parent):QWidget(parent)
{
? ? setMinimumSize(200,120);
? ? setMaximumSize(200,120);
? ? QPushButton *quit = new QPushButton("quit",this);
? ? quit->setGeometry(62,40,75,30);
}
//析構函數
MyWidget::~MyWidget()
{
? ? //不用做什么
}
//主函數
int main(int argc, char *argv[])
{
? ? QApplication app(argc, argv);
? ? MyWidget w;
? ? w.setGeometry(100,100,200,120);
? ? w.show();
? ??
? ? return app.exec();
}
這個例子中有一個“QPushButton”類型的指針“quit”,它有父對象。所以它隨著
父對象一起銷毀。不需要擔心內存的問題。實際上是Qt幫忙解決了。
4、聲明為變量的風險
下面是一個錯誤的例子,它可以編譯成可執行文件,但它會在程序結束時崩潰
#include <QApplication>
#include <QWidget>
#include <QLabel>
int main(int argc, char* argv[])
{
? ? QApplication app(argc, argv);
? ??
? ? QLabel label("Hello Qt!"); ? ?
? ? QWidget w;
? ? label.setParent(&w);
? ? w.show();
? ? return app.exec();
}
因為退出時,w比label先被析構,當w被析構時,會刪除chilren列表中的對象,
也就是這兒的label。但label卻不是通過new分配在heap中,而是在stack中,可
想而知,delete一個再stack中的對象會怎么樣了。下面的程序是正確的
#include <QApplication>
#include <QWidget>
#include <QLabel>
int main(int argc, char* argv[])
{
? ? QApplication app(argc, argv);
? ??
? ? QWidget w;
? ? QLabel label("Hello Qt!"); ? ?
? ? label.setParent(&w);
? ? w.show();
? ? return app.exec();
}
這個程序僅僅是聲明變量的時候換了個順序。于是運行正確了。這樣可以確保
label先于其parent被析構。這樣label析構時將自己從父對象的列表中移除自己,
w析構時,children列表中就不會有分配在stack中的對象了。
總結
以上是生活随笔為你收集整理的qt中new与delete使用示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#中模态对话框释放问题
- 下一篇: 解决:java.lang.Illegal