(Qt Creator - приложение на основе Cpp) Q <Objects>VS используя указатели? - PullRequest
0 голосов
/ 22 сентября 2011

вот мой код:

//MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui>

class MainWindow : public QWidget
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    QTextEdit *textEdit;
};


#endif // MAINWINDOW_H

// MainWindow.cpp
#include "mainwindow.h"
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent)
{
textEdit = new QTextEdit();
}

MainWindow::~MainWindow()
{
    delete textEdit;
}

//main.cpp
#include <QtGui>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

Является ли более эффективным (вот часть вопроса «Q [Objects] VS используя указатели?»): 1) Используйте указатели, как я на самом деле или

2) Использовать объекты (удаление * + оператор удаления)

Спасибо!

Ответы [ 3 ]

6 голосов
/ 22 сентября 2011
MainWindow::MainWindow(QWidget *parent)
{
textEdit = new QTextEdit(this);
}

MainWindow::~MainWindow()
{
}
2 голосов
/ 26 сентября 2011

Для QObject членов в качестве указателей не следует использовать delete, QTextEdit, вероятно, будет дочерним по отношению к MainWindow, поэтому он будет удален автоматически.

Конечно, теоретически было бы быстрее использовать не указатели QObject членов с одним меньшим уровнем косвенности. Вот так (для тех, кто не понял вопроса):

class MainWindow : public QMainWindow {
   ...
private:
   QTextEdit textEdit;
};

и кода для ввода меньше, потому что вам не нужно повторно вводить имя класса членов, чтобы инициализировать их в конструкторе.

Но поскольку QObject сами уже интенсивно используют косвенное обращение (с их d-указателем ), усиление, вероятно, будет незначительным. А дополнительный код, который вы вводите с помощью элементов указателя, позволяет вам иметь меньшую связь между вашими заголовочными файлами и Qt, потому что вы можете использовать предварительные объявления вместо включения заголовков, что означает более быструю компиляцию (особенно если вы не с использованием предварительно скомпилированных заголовков) и перекомпиляции.

Также

  • удаление элементов указателя QObject вручную или
  • объявление QObject членами, не указавшими

может привести к двойному удалению, если вы соответственно не удаляете / не объявляете их в правильном порядке (потомки потом родители для удаления или родители потом дети для объявления).
Например:

class MainWindow : public QMainWindow {
   ...
private:
   QTextEdit textEdit; 
   QScrollArea scrollArea;
};

MainWindow::MainWindow() {
   setCentralWidget(&scrollArea);
   QWidget *scrolledWidget = new QWidget(&scrollArea);
   QVBoxLayout *lay = new QVBoxLayout(scrolledWidget);
   lay->addWidget(...);
   lay->addWidget(&textEdit); // textEdit becomes a grand-child of scrollArea
   scrollArea.setWidget(scrolledWidget);
}

Когда MainWindow удаляется, его нестатические члены класса удаляются в порядке, обратном их объявлению в классе. Итак, scrollArea сначала уничтожается, затем textEdit, но scrollArea также уничтожает его потомков, включая textEdit, поэтому textEdit эффективно уничтожается дважды, вызывая сбой.

Таким образом, менее подвержено ошибкам использование QObject членов в качестве указателей и не удаление QObject, у которых есть родительский элемент самостоятельно.

1 голос
/ 23 сентября 2011

Попробуйте создать QLineEdit в стеке, а затем поместить его в макет ... Выйти из приложения ... Что вы видите?СОВЕТ: запустите ваше приложение в отладчике.

ksming прав насчет чтения документации.Это не проблема конкретного языка.Если вы спрашиваете, что быстрее: выделение кучи или стека, то правильно сформулируйте свой вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...