【发布时间】:2018-11-17 01:43:53
【问题描述】:
据我了解,以下代码是创建 QObject 的绝佳方式
QLabel *label = new QLabel("label");
QWidget window;
label->setParent(&window);
window.show();
当我阅读无处不在时,“父对象拥有新创建对象的所有权 - 并最终调用删除”,或者“复合对象拥有子对象的所有权,只要育儿有搞定了,你可以放心,当父级被销毁时,子级QObjects也会被销毁”(来自How does Qt delete objects ? And what is the best way to store QObjects?)
谁能告诉我 Qt 如何“获得”一个 QObject 的所有权?从技术上讲:Qt(它是一个库并有自己的运行时)如何在我用来自不同的操作符 new 创建的指针上调用操作符 delete运行?为什么不崩溃?
编辑
我正在添加此参考,因为问题的全部意义来自于此:
“在 DLL 中运行的代码可能使用不同的 C++ 运行时库,这意味着堆的布局将不同。DLL 可能完全使用不同的堆。
在 DLL 分配的指针上调用 delete(在主程序中)(反之亦然)将导致(最好的情况)立即崩溃或(最坏的情况)内存损坏,这需要一段时间才能找到。 "(来自C++ mix new/delete between libs?)
【问题讨论】:
-
你可能太努力了。 :-) Qt 代码将执行
delete label;,就像您的代码可以执行的操作一样。没有区别,没有魔法。 -
但 Qt 的删除操作符与我的不同,因为库有自己的新/删除操作符,不应混合在 DLL 中运行的代码可能使用不同的 C++ 运行时库,这意味着堆的布局会有所不同。 DLL 可能完全使用不同的堆。
-
问题的新部分是关于别的东西。如果你随机混合 DLL,比如一些 Debug 模式和一些 Release 模式,或者使用不同的编译器,你会遇到问题。但是,如果所有内容都使用相同的编译器使用相同的设置进行编译,那么所有内容都将使用相同的语言运行时。然后就没有问题了。
-
您必须使用使用相同编译器编译的 Qt 工具包,因此(至少在 Windows 上),我们有不同的工具包代表相同版本的 Qt,但使用不同的编译器编译...
-
我有错误的假设,即即使使用相同的编译器、版本或配置也可能存在多个堆管理。谢谢