此代码不动态分配内存,不会在窗口上显示任何标签。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QLabel l;
l.setText ("cdsadsaf");
l.setParent (this);
}
动态分配内存后,标签会显示。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QLabel *label = new QLabel(this);
label->setText("first line\nsecond line");
}
为什么QLabel必须使用动态内存分配?
答案 0 :(得分:5)
不需要。这里有典型的范围问题。
第一种情况是在堆栈上创建QLabel
并且它会死掉"当你退出构造函数时。
在第二部分,它继续生活1)因为它是动态分配的,2)你实际上是为它分配一个父 - 这是你的主窗口。如果你不做2),效果将与第一种情况相同,但更糟糕的是 - 你将创建内存泄漏:
内存泄漏
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QLabel *label = new QLabel(); # no parent
label->setText("first line\nsecond line");
}
由于父级被分配到标签而没有内存泄漏
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QLabel *label = new QLabel(this); # main window is the parent and will take care of destroying the label when its own destructor is called
label->setText("first line\nsecond line");
}
您可以避免在堆上分配QLabel
,但仍然可以通过将其移动到更广泛的范围来使用它。由于您的标签将显示在主窗口中,因此您可以创建类成员标签。不需要动态分配,因为只要您的窗口实例处于活动状态,它就会继续生效。
class MainWindow : public QMainWindow
{
...
private:
QLabel l;
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
this->l.setText ("cdsadsaf");
}
正如评论中所提到的(再次感谢!)此处不需要setParent(...)
,除非您想要除了内存管理以外的其他内容的父子关系。见下面的评论。
答案 1 :(得分:2)
此代码不动态分配内存,不会在窗口上显示任何标签。
那是因为一旦从构造函数返回,标签就会超出范围。标签的生命周期在下面注明。 if (window.location.hash) {
$('li').one('click',function () {
if (!window.run){
$(this).prependTo($(this).parent());
window.run = true;
}
});
$(document).ready(function () {
var id = window.location.hash;
$(id).trigger('click');
});
}
<{1}}本身。
label
动态分配内存后,标签会显示。
那是因为标签不在范围之外。指向它的指针确实如此,但这并不重要。请注意,QLabel
仅仅是一个指针,MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QLabel label; // label is born
label.setText ("cdsadsaf"); // label is alive
label.setParent (this); // label is alive
} // label dies
对象的存在与指向它的指针无关。
label
为什么QLabel必须使用动态内存分配?
不是。你碰巧给了QLabel
使用动态分配的机会,但这只是一个巧合。
您可以将标签作为父对象本身的一部分 - 然后它不再需要单独的分配。编译器将为您管理内存。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QLabel *label = new QLabel(this); // label is born, QLabel is born
label->setText("first line\nsecond line"); // label is alive, QLabel is alive
} // label dies, QLabel is alive
答案 2 :(得分:1)
在堆栈上创建QLabel
时,函数返回时会删除它。当父窗口小部件更新其显示时,QLabel
不再存在。
在堆上创建它可以使它超出对函数的调用。