Qt如何删除QObjects?

时间:2018-06-07 08:17:50

标签: c++ qt qt4

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

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

当我正在阅读无处不在"父母取得新创建的对象的所有权 - 并最终调用delete"或"复合对象取得子女的所有权因此,只要完成了父母教育,就可以确保当父母被销毁时孩子QObjects将被销毁。 (来自How does Qt delete objects ? And what is the best way to store QObjects?

有人能告诉我Qt"取得所有权"一个QObject?更技术性的:Qt(它是一个库并有自己的运行时)如何在一个我用不同的运算符 new 创建的指针上调用operator delete 运行?为什么不崩溃?

修改

我正在添加此引用,因为问题的全部内容来自于此:

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

在DLL分配的指针上调用delete(在主程序中)(反之亦然)将导致(最多)立即崩溃或(最坏)内存损坏,需要一段时间才能跟踪向下&#34。 (来自C++ mix new/delete between libs?

2 个答案:

答案 0 :(得分:4)

让源代码说话而不仅仅是答案。这是QObject's internals做的事情:

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

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

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

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

答案 1 :(得分:1)

  

for Qt(这是一个库并有自己的运行时)

这是你的假设错误的地方。首先,没有&#34;运行时&#34;对于操作系统。 &#34;运行&#34;是一个信息性术语。

现代操作系统包括:二进制可执行文件,共享库,动态链接库,DLL,静态库,进程,线程等。

在这种情况下,您的可执行文件和Qt共享库被加载到SAME进程中,这意味着它们之间共享内存。这意味着你的可执行文件可以看到Qt内存,相反Qt可以看到你的内存。