Qt如何删除QObjects?
how can Qt delete QObjects?
据我了解,以下代码是创建 QObject 的完美方式
QLabel *label = new QLabel("label");
QWidget window;
label->setParent(&window);
window.show();
因为我正在阅读无处不在 "the parent takes ownership of the newly created object - and eventually calls delete",或"the composite object takes ownership of the children so, as long as the parenting has been done, you can be assured that the child QObjects will be destroyed when the parent is destroyed"(来自How does Qt delete objects ? And what is the best way to store QObjects?)
谁能告诉我Qt "take ownership" 怎么能有一个QObject?从技术上讲:Qt(它是一个库,有自己的运行时)怎么可能在我用运算符 new[= 创建的指针上调用运算符 delete 32=] 来自不同的运行时?为什么它不崩溃?
编辑
我正在添加此参考,因为问题的全部要点来自于此:
“DLL 中的代码 运行 可能使用了不同的 C++ 运行时库,这意味着堆的布局将不同。DLL 可能使用了完全不同的堆。
在 DLL 分配的指针上调用 delete(在主程序中)(反之亦然)将导致(充其量)立即崩溃或(最坏)导致需要一段时间才能跟踪的内存损坏下来。”(来自 C++ mix new/delete between libs?)
for Qt (which is a library and has its own runtime)
这是你的假设错误的地方。首先,OS 没有 "runtime" 这样的东西。 "Runtime" 是一个信息术语。
现代操作系统有这样的东西:二进制可执行文件、共享库又名动态链接库又名 DLL、静态库、进程、线程等。
在这种情况下,您的可执行文件和 Qt 共享库被加载到同一个进程中,这意味着内存在它们之间共享。这意味着您的可执行文件可以看到 Qt 内存,相反 Qt 可以看到您的内存。
让源码说话,让源码说话。这是 QObject's internals 所做的:
for (int i = 0; i < children.count(); ++i) {
currentChildBeingDeleted = children.at(i);
children[i] = 0;
delete currentChildBeingDeleted;
}
children.clear();
上面代码的函数在析构函数中被调用。所以,这很简单。父级存储指向其所有子级的指针。当调用父级的析构函数时,它会删除所有子级。这是递归的,因为在对象上调用 delete
会调用其析构函数
为什么Qt可以安全删除而不用担心运行时库
实际上,由于名称修改,导出 C++ 接口几乎迫使您使用相同版本的编译器和运行时库。这种非常粗略的方式允许 Qt 假设 delete
可以安全调用。
据我了解,以下代码是创建 QObject 的完美方式
QLabel *label = new QLabel("label");
QWidget window;
label->setParent(&window);
window.show();
因为我正在阅读无处不在 "the parent takes ownership of the newly created object - and eventually calls delete",或"the composite object takes ownership of the children so, as long as the parenting has been done, you can be assured that the child QObjects will be destroyed when the parent is destroyed"(来自How does Qt delete objects ? And what is the best way to store QObjects?)
谁能告诉我Qt "take ownership" 怎么能有一个QObject?从技术上讲:Qt(它是一个库,有自己的运行时)怎么可能在我用运算符 new[= 创建的指针上调用运算符 delete 32=] 来自不同的运行时?为什么它不崩溃?
编辑
我正在添加此参考,因为问题的全部要点来自于此:
“DLL 中的代码 运行 可能使用了不同的 C++ 运行时库,这意味着堆的布局将不同。DLL 可能使用了完全不同的堆。
在 DLL 分配的指针上调用 delete(在主程序中)(反之亦然)将导致(充其量)立即崩溃或(最坏)导致需要一段时间才能跟踪的内存损坏下来。”(来自 C++ mix new/delete between libs?)
for Qt (which is a library and has its own runtime)
这是你的假设错误的地方。首先,OS 没有 "runtime" 这样的东西。 "Runtime" 是一个信息术语。
现代操作系统有这样的东西:二进制可执行文件、共享库又名动态链接库又名 DLL、静态库、进程、线程等。
在这种情况下,您的可执行文件和 Qt 共享库被加载到同一个进程中,这意味着内存在它们之间共享。这意味着您的可执行文件可以看到 Qt 内存,相反 Qt 可以看到您的内存。
让源码说话,让源码说话。这是 QObject's internals 所做的:
for (int i = 0; i < children.count(); ++i) {
currentChildBeingDeleted = children.at(i);
children[i] = 0;
delete currentChildBeingDeleted;
}
children.clear();
上面代码的函数在析构函数中被调用。所以,这很简单。父级存储指向其所有子级的指针。当调用父级的析构函数时,它会删除所有子级。这是递归的,因为在对象上调用 delete
会调用其析构函数
为什么Qt可以安全删除而不用担心运行时库
实际上,由于名称修改,导出 C++ 接口几乎迫使您使用相同版本的编译器和运行时库。这种非常粗略的方式允许 Qt 假设 delete
可以安全调用。