qt中new与delete使用示例
qt中有時(shí)候使用new后并沒(méi)有使用delete,原因是
Qt?自動(dòng)回收是靠父子關(guān)系。父親銷毀了。他的孩子也銷毀。
delete(Qobject* obj)//有時(shí)需要手動(dòng)銷毀
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之后不需要執(zhí)行delete,因?yàn)閘abel的父類是w,而w是在棧中創(chuàng)建,在程序關(guān)閉的時(shí)候會(huì)自動(dòng)釋放,所以作為w的子類內(nèi)存也被釋放。
? ? QLabel *label1 =new QLabel("world");
? ? //這個(gè)是需要執(zhí)行delete label1,否則會(huì)造成內(nèi)存泄漏,因?yàn)閘abel沒(méi)有父類,所以不會(huì)為label釋放內(nèi)存
? ? w.show();
? ? a.exec();
? ? delete label1;
? ? label1=NULL;
? ? return 0;
}
?
總的來(lái)說(shuō),Qt的對(duì)象如果使用new聲明為指針,那么:(1)如果它沒(méi)有父對(duì)象,
可以在不需要的使用使用delete把它釋放。(2)如果它有父對(duì)象,會(huì)在父對(duì)象
銷毀的時(shí)候同時(shí)被銷毀。父對(duì)象什么時(shí)候銷毀參見(jiàn)第一條。下面是一些例子。
1、使用delete
這個(gè)例子如下
//第一個(gè)程序
#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();
}
//第二個(gè)程序
#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();
? ? //釋放內(nèi)存
? ? delete label;
? ??
? ? return ret;
}
因?yàn)閘abel沒(méi)有父對(duì)象,所以它的釋放只能自己來(lái)。第一個(gè)程序沒(méi)有釋放內(nèi)存。
第二個(gè)程序使用了delete釋放了內(nèi)存。
2、使用標(biāo)志位
使用標(biāo)志位可以不顯示的使用delete,但和使用delete是一樣的。因?yàn)镼t在暗中
使用了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();
}
下面是一個(gè)暗中使用delete的例子。這是一個(gè)類,它有一個(gè)成員函數(shù),可以刪除
自己。當(dāng)然只能刪除由關(guān)鍵字new創(chuàng)建的自己。
#include<iostream>
using namespace std;
//類AAA
class AAA
{
public:
? ? //構(gòu)造函數(shù)
? ? AAA();
? ? ~AAA(void);
? ? void delete_me(void);
};
//構(gòu)造函數(shù)
AAA::AAA(void)
{
? ? //空的
}
//析構(gòu)函數(shù)
AAA::~AAA(void)
{
? ? //空的
}
//刪除自己
void AAA::delete_me(void)
{
? ? delete this;
}
?
?
?
//主函數(shù)
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、依靠父對(duì)象
下面是第二種情況。例子如下
#include <QApplication>
#include <QWidget>
#include <QPushButton>
//自定義類
class MyWidget : public QWidget
{
public:
? ? MyWidget(QWidget *parent = 0);
? ? ~MyWidget();
};
//構(gòu)造函數(shù)
MyWidget::MyWidget(QWidget *parent):QWidget(parent)
{
? ? setMinimumSize(200,120);
? ? setMaximumSize(200,120);
? ? QPushButton *quit = new QPushButton("quit",this);
? ? quit->setGeometry(62,40,75,30);
}
//析構(gòu)函數(shù)
MyWidget::~MyWidget()
{
? ? //不用做什么
}
//主函數(shù)
int main(int argc, char *argv[])
{
? ? QApplication app(argc, argv);
? ? MyWidget w;
? ? w.setGeometry(100,100,200,120);
? ? w.show();
? ??
? ? return app.exec();
}
這個(gè)例子中有一個(gè)“QPushButton”類型的指針“quit”,它有父對(duì)象。所以它隨著
父對(duì)象一起銷毀。不需要擔(dān)心內(nèi)存的問(wèn)題。實(shí)際上是Qt幫忙解決了。
4、聲明為變量的風(fēng)險(xiǎn)
下面是一個(gè)錯(cuò)誤的例子,它可以編譯成可執(zhí)行文件,但它會(huì)在程序結(jié)束時(shí)崩潰
#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();
}
因?yàn)橥顺鰰r(shí),w比label先被析構(gòu),當(dāng)w被析構(gòu)時(shí),會(huì)刪除chilren列表中的對(duì)象,
也就是這兒的label。但label卻不是通過(guò)new分配在heap中,而是在stack中,可
想而知,delete一個(gè)再stack中的對(duì)象會(huì)怎么樣了。下面的程序是正確的
#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();
}
這個(gè)程序僅僅是聲明變量的時(shí)候換了個(gè)順序。于是運(yùn)行正確了。這樣可以確保
label先于其parent被析構(gòu)。這樣label析構(gòu)時(shí)將自己從父對(duì)象的列表中移除自己,
w析構(gòu)時(shí),children列表中就不會(huì)有分配在stack中的對(duì)象了。
總結(jié)
以上是生活随笔為你收集整理的qt中new与delete使用示例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C#中模态对话框释放问题
- 下一篇: 解决:java.lang.Illegal