Управление памятью в QT?

Я довольно плохо знаком с QT и задаюсь вопросом на некотором основном материале с управлением памятью и жизнью объектов. Когда я должен удалить и/или уничтожить свои объекты? Какое-либо из этого обрабатывается автоматически?

В примере ниже, который из объектов я создаю, я должен удалить? Что происходит с переменной экземпляра myOtherClass когда myClass уничтожается? Что происходит, если я не удаляю (или уничтожаю), мои объекты вообще? Это будет проблемой к памяти?

MyClass.h

class MyClass
{

public:
    MyClass();
    ~MyClass();
    MyOtherClass *myOtherClass;
};

MyClass.cpp

MyClass::MyClass() {
    myOtherClass = new MyOtherClass();

    MyOtherClass myOtherClass2;

    QString myString = "Hello";
}

Поскольку Вы видите, что это - довольно легкий для новичка материал, но где я могу узнать об этом в простом способе?

91
задан nbro 22 September 2016 в 20:58
поделиться

3 ответа

Я хотел бы расширить ответ Дебильски, указав, что концепция владения очень важна в Qt. Когда класс A принимает на себя владение классом B, класс B удаляется, когда класс A удаляется. Есть несколько ситуаций, когда один объект становится владельцем другого, а не только тогда, когда вы создаете объект и указываете его родителя.

Например:

QVBoxLayout* layout = new QVBoxLayout;
QPushButton someButton = new QPushButton; // No owner specified.
layout->addWidget(someButton); // someButton still has no owner.
QWidget* widget = new QWidget;
widget->setLayout(layout); // someButton is "re-parented".
                           // widget now owns someButton.

Другой пример:

QMainWindow* window = new QMainWindow;
QWidget* widget = new QWidget; //widget has no owner
window->setCentralWidget(widget); //widget is now owned by window.

Итак, часто проверяйте документацию, она обычно указывает, повлияет ли метод на владение объектом.

Как заявил Дебильски, эти правила применяются ТОЛЬКО к объектам, которые являются производными от QObject. Если ваш класс не является производным от QObject, вам придется справиться с разрушением самостоятельно.

47
ответ дан 24 November 2019 в 06:48
поделиться

Если вы строите свою собственную иерархию с помощью QObject s, то есть инициализируете все вновь созданные QObject s с родителем

QObject* parent = new QObject();
QObject* child = new QObject(parent);

, тогда достаточно удалить родительский , потому что деструктор родительского позаботится об уничтожении дочернего ]. (Он делает это путем выдачи сигналов, поэтому это безопасно, даже когда вы удаляете дочерний вручную перед родительским.)

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

Если ваш MyClass не является дочерним по отношению к QObject , вам придется использовать простой способ работы C ++.

Также обратите внимание, что иерархия родитель-потомок QObject s обычно не зависит от иерархии дерева иерархии / наследования классов C ++. Это означает, что назначенный дочерний элемент не обязательно должен быть прямым подклассом своего родителя . Подойдет любой (подкласс) QObject .

Однако конструкторы могут накладывать некоторые ограничения по другим причинам; например, в QWidget (QWidget * parent = 0) , где родительский элемент должен быть другим QWidget , например, из-за флаги видимости и потому, что таким образом вы сделаете базовый макет; но для системы иерархии Qt в целом вам разрешено иметь любой QObject в качестве родителя.

96
ответ дан 24 November 2019 в 06:48
поделиться

Родитель (объект QObject или его производный класс) имеет список указателей на его дочерние элементы (QObject / его производные). Родитель удалит все объекты в своем дочернем списке, пока родитель будет уничтожен. Вы можете использовать это свойство QObject, чтобы автоматически удалять дочерние объекты при удалении родителя. Отношение может быть установлено с помощью следующего кода

QObject* parent = new QObject();
QObject* child = new QObject(parent);
delete parent;//all the child objects will get deleted when parent is deleted, child object which are deleted before the parent object is removed from the parent's child list so those destructor will not get called once again.

Есть другой способ управлять памятью в Qt, используя smartpointer. В следующей статье описаны различные интеллектуальные указатели в Qt. https://blog.qt.digia.com/blog/2009/08/25/count-with-me-how-many-smart-pointer-classes-does-qt-have/

7
ответ дан 24 November 2019 в 06:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: