关于QMainWindow构造函数中UI小部件的'new'用法的困惑

时间:2012-01-02 08:30:04

标签: c++ pointers qt4 memory-management widget

使用Qt的编码练习最好描述如下:

  1. 如果要主动使用Widget(例如提供文本的A QLineEdit),我会在头文件中声明它,然后在MainWindow.cpp中初始化它。 例如TextEditor.h:
  2. class TextEditor { //other code private: QLineEdit edtFind; };

    2 ..如果不打算使用小部件(例如QLabelQWidget),或者它是信号槽系统的一部分(例如QPushButton),我在构造函数中声明并初始化它使用新的。

    -e.g。

    TextEditor::TextEditor()
    {
       //other code
       QWidget* searchPanel = new QWidget();
       edtFind = new QLineEdit("Enter Search Term");
       QPushButton* findButton = new QPushButton("Find");
       connect(findButton,SIGNAL(pressed()),this,SLOT(find()));
    
       ui->statusbar->addPermanentWidget(searchPanel);
    }
    

    我的问题是,我是否在第2点采用了有效的方法?不从堆中分配内存会更好吗?

    感谢。

2 个答案:

答案 0 :(得分:2)

您的方法效率不高。您应该在实际需要时使用堆分配的对象:

  • 具有更长生命周期的对象
  • 使用前向声明以避免包含头文件
  • 持有对在别处创建的对象的引用

您的方法更复杂,没有任何明显的好处。众所周知,堆很慢,并且已知分配大量小对象会将其分段(这可能不会对您的应用产生影响,但这仍然是一种不好的做法)。

答案 1 :(得分:1)

虽然对C ++提出了很好的建议,但答案1在Qt:QObject(以及所有小部件,因为QWidget派生自QObject)中占很大比例实际上是错误的。如果QObject具有父级,则规则始终在堆上分配QObject,因为QObject具有基于父级的垃圾收集(当最顶层的QObject-parent被删除时,它将要求其所有子级递归删除它们)。应用程序可能会尝试删除堆栈中的对象,从而导致崩溃。

请注意,Qt中的某些操作会隐式添加或更改QObject的父级作为副作用(重新显示),例如将小部件添加到布局。但是,这通常记录在API文档中。由于重新定位在QWidgets中非常常见,因此不应将它们放在堆栈中。其他QObject派生类更安全,如有疑问请查阅API文档。