Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么我必须为QLabel动态分配内存才能使其工作?_C++_Qt_Dynamic Memory Allocation_Qlabel - Fatal编程技术网

C++ 为什么我必须为QLabel动态分配内存才能使其工作?

C++ 为什么我必须为QLabel动态分配内存才能使其工作?,c++,qt,dynamic-memory-allocation,qlabel,C++,Qt,Dynamic Memory Allocation,Qlabel,此代码不会动态分配内存,不会在窗口上显示任何标签 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QLabel l; l.setText ("cdsadsaf"); l.setParent (this); } 动态分配内存后,将显示标签 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { Q

此代码不会动态分配内存,不会在窗口上显示任何标签

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需要动态内存分配才能工作?

在堆栈上创建
QLabel
时,当函数返回时,它会被删除。当父窗口小部件更新其显示时,
QLabel
不再存在


在堆上创建它允许它在调用函数之后继续存在。

在堆栈上创建
QLabel
时,函数返回时它会被删除。当父窗口小部件更新其显示时,
QLabel
不再存在


在堆上创建它允许它在调用函数之后继续存在。

这不是必需的。这里有典型的范围问题

第一种情况是在堆栈上创建
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(…)
在这里不是必需的,除非您希望为内存管理以外的内容建立父子关系。请参阅下面的注释。

这不是必需的。这里有典型的范围问题

第一种情况是在堆栈上创建
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(…)
在这里不是必需的,除非您希望为内存管理以外的内容建立父子关系。见下面的评论

此代码不会动态分配内存,不会在窗口上显示任何标签

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QLabel l;
    l.setText ("cdsadsaf");
    l.setParent (this);
}
这是因为一旦您从构造函数返回,标签就会超出范围。标签的生命周期如下所示。
标签本身就是一个
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
动态分配内存后,将显示标签

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QLabel *label = new QLabel(this);
    label->setText("first line\nsecond line");
}
这是因为标签没有超出范围。指向它的指针可以,但这并不重要。请注意,
label
只是一个指针,而
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
为什么QLabel工作需要动态内存分配

不是。由于使用了动态分配,您碰巧给了
QLabel一个生存的机会,但这只是巧合

您可以将标签作为父对象本身的一部分,这样就不需要单独分配。编译器将为您管理内存

#include <QtWidgets>

class MainWindow : public QMainWindow {
  QWidget m_central;
  QGridLayout m_layout{&m_central};
  QLabel m_label{"Hello, World"};
public:
  MainWindow(QWidget * parent = {}) : QMainWindow{parent} {
    m_layout.addWidget(&m_label, 0, 0);
    setCentralWidget(&m_central);
  }
};

int main(int argc, char ** argv) {
  QApplication app{argc, argv};
  MainWindow w;
  w.show();
  return app.exec();
}
#包括
类主窗口:公共QMainWindow{
九龙文娱艺术中心;;
QGridLayout m_layout{&m_central};
QLabel m_标签{“你好,世界”};
公众:
主窗口(QWidget*parent={}):QMainWindow{parent}{
m_layout.addWidget(&m_标签,0,0);
setCentralWidget(&m_central);
}
};
int main(int argc,字符**argv){
QApplication app{argc,argv};
主窗口w;
w、 show();
返回app.exec();
}
此代码不会动态分配内存,不会在窗口上显示任何标签

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QLabel l;
    l.setText ("cdsadsaf");
    l.setParent (this);
}
这是因为一旦您从构造函数返回,标签就会超出范围。标签的生命周期如下所示。
标签本身就是一个
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
动态分配内存后,将显示标签

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QLabel *label = new QLabel(this);
    label->setText("first line\nsecond line");
}
这是因为标签没有超出范围。指向它的指针可以,但这并不重要。请注意,
label
只是一个指针,而
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
为什么QLabel工作需要动态内存分配

不是。由于使用了动态分配,您碰巧给了
QLabel一个生存的机会,但这只是巧合

您可以将标签作为父对象本身的一部分,这样就不需要单独分配。编译器将为您管理内存

#include <QtWidgets>

class MainWindow : public QMainWindow {
  QWidget m_central;
  QGridLayout m_layout{&m_central};
  QLabel m_label{"Hello, World"};
public:
  MainWindow(QWidget * parent = {}) : QMainWindow{parent} {
    m_layout.addWidget(&m_label, 0, 0);
    setCentralWidget(&m_central);
  }
};

int main(int argc, char ** argv) {
  QApplication app{argc, argv};
  MainWindow w;
  w.show();
  return app.exec();
}
#包括
类主窗口:公共QMainWindow{
九龙文娱艺术中心;;
QGridLayout m_layout{&m_central};
QLabel m_标签{“你好,世界”};
公众:
主窗口(QWidget*parent={}):QMainWindow{parent}{
m_layout.addWidget(&m_标签,0,0);
setCentralWidget(&m_central);
}
};
int main(int argc,字符**argv){
QApplication app{argc,argv};
主窗口w;
w、 show();
返回app.exec();
}

如果您在类成员的小部件上调用
setParent
,它不会被删除吗