首页 > 解决方案 > Qt如何删除QObjects?

问题描述

据我了解,以下代码是创建 QObject 的完美方法

QLabel *label = new QLabel("label");
QWidget window;
label->setParent(&window);
window.show();

当我到处读到“父对象拥有新创建对象的所有权 - 并最终调用删除”,或者“复合对象拥有子对象的所有权,所以只要完成了育儿,您就可以放心,孩子当父对象被销毁时,QObjects 将被销毁”(来自Qt 如何删除对象?以及存储 QObjects 的最佳方式是什么?

有人能告诉我 Qt 如何“获得”QObject 的所有权吗?从技术上讲:Qt(它是一个库并且有自己的运行时)如何在我使用来自不同运行时的运算符创建的指针上调用运算符删除?为什么不崩溃?

编辑

我添加了这个参考,因为问题的重点来自于此:

“在 DLL 中运行的代码可能使用不同的 C++ 运行时库,这意味着堆的布局将不同。DLL 可能完全使用不同的堆。

在 DLL 分配的指针上调用 delete(在主程序中)(反之亦然)将导致(最好的​​情况)立即崩溃或(最坏的情况)内存损坏,这需要一段时间才能追踪。”(来自C ++在库之间混合新/删除?

标签: c++qtqt4

解决方案


让源代码说话,而不仅仅是答案。这是QObject 的内部结构:

for (int i = 0; i < children.count(); ++i) {
    currentChildBeingDeleted = children.at(i);
    children[i] = 0;
    delete currentChildBeingDeleted;
}
children.clear();

上面代码的函数在析构函数中被调用。所以,这很简单。父级存储指向其所有子级的指针。当调用父级的析构函数时,它会删除它的所有子级。这是递归的,因为调用delete对象调用它的析构函数

为什么 Qt 可以安全删除而不用担心运行时库

实际上,由于名称混淆,导出 C++ 接口几乎迫使您使用相同版本的编译器和运行时库。这以非常粗略的方式允许 Qt 假设delete调用是安全的。


推荐阅读