Путаница в использовании новых для виджетов пользовательского интерфейса в конструкторе QMainWindow - PullRequest
1 голос
/ 02 января 2012

Моя практика кодирования с использованием Qt может быть лучше всего описана следующим образом:

  1. Если виджет будет активно использоваться (например, QLineEdit, который предоставляет текст), я объявляю его в заголовочном файле, а затем инициализирую его в MainWindow.cpp. например TextEditor.h:

class TextEditor { //other code private: QLineEdit edtFind; };

2 .. Если виджет не будет использоваться (например, QLabel, QWidget) или является частью системы слотов сигналов (например, QPushButton), я объявляю и инициализирую его внутри конструктора, используя new.

-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 ]

2 голосов
/ 02 января 2012

Ваш подход не эффективен. Вы должны использовать объекты, выделенные кучей, когда они вам действительно нужны:

  • объекты с более длительным сроком службы
  • использование предварительного объявления, чтобы избежать включения заголовочного файла
  • содержит ссылку на объект, созданный в другом месте

Ваш подход более сложен без видимой выгоды. Известно, что куча медленная, и выделение большого количества мелких объектов, как известно, фрагментирует ее (это может не иметь значения в вашем приложении, но это по-прежнему плохая практика).

1 голос
/ 02 января 2012

Хотя хороший совет для C ++ в целом, ответ 1 на самом деле неверен для большей части Qt: QObject (и вместе с ним всех виджетов, поскольку QWidget наследуется от QObject). Правило всегда заключается в том, чтобы всегда размещать объекты QObject в куче, если у них есть родитель, поскольку QObject поддерживает сборку мусора на основе родителей (когда удаляется самый верхний родительский объект QObject, он попросит всех своих дочерних элементов рекурсивно удалить себя). Приложение может попытаться удалить объект в стеке, что приводит к сбою.

Обратите внимание, что некоторые операции в Qt неявно добавляют или изменяют родителя QObject как побочный эффект (переопределение), такой как добавление виджета в макет. Однако это обычно документируется в документации API. Так как повторное воспитание очень распространено в QWidgets, вы никогда не должны помещать их в стек. Другие классы, производные от QObject, более безопасны, в случае сомнений обратитесь к документации API.

...