当前位置:  开发笔记 > 编程语言 > 正文

为什么官方Qt示例和教程不使用智能指针?

如何解决《为什么官方Qt示例和教程不使用智能指针?》经验,为你挑选了5个好方法。

为什么关于Qt库的官方示例和教程从不使用智能指针?我只看到newdelete创建和销毁小部件.

我搜索了理由但我找不到它,我自己也没有看到它,除非它是出于历史原因或向后兼容性:不是每个人都希望程序在窗口小部件构造函数失败时终止,并通过try/catch处理它块只是丑陋(即使在少数地方使用).父小工具可能取得孩子的所有权这一事实也只能部分地解释我的事情,因为你仍然需要delete在某种程度上为父母使用.



1> UmNyobe..:

因为Qt依赖父子模型来管理Qobject资源.它遵循复合+责任链模式,从事件管理到内存管理,绘图,文件处理等......

实际上,尝试在共享\唯一指针中使用QObject 是过度工程(99%的时间).

    您必须提供一个自定义删除器,它将调用deleteLater

    您父母的qobject已在父对象中有引用.所以你知道只要父元素存在,对象就不会泄露.当你需要摆脱它时,你可以deleteLater直接打电话.

    没有父项的QWidget已经在Qapplication对象中有了引用.与第2点相同.

也就是说,你仍然可以在Qt中使用RAII.例如,QPointer在a上表现为弱引用QObject.我会用QPointer而不是QWidget*.

注意:听起来不是太狂热,两个字:Qt + valgrind.


[文档警告你反对它](http://doc.qt.io/qt-5/qobject.html#dtor.QObject).直接调用delete可能会导致因对象(或其子对象)的挂起事件\排队连接而导致崩溃.

2> Ralph Tandet..:

智能指针给孩子们

智能指针类std::unique_ptr,std::shared_ptr用于内存管理.拥有这样一个智能指针意味着你拥有指针.但是,在QObject使用QObject父级创建或派生类型时,所有权(清理的责任)将移交给父级QObject.在这种情况下,标准库智能指针是不必要的,甚至是危险的,因为它们可能会导致双重删除.哎呀!

孤儿的原始指针

但是,当QObject在堆上创建(或派生类型)而没有父项时,QObject事物是非常不同的.在这种情况下,你不应该只是持有一个原始指针,而是一个智能指针,最好是一个std::unique_ptr对象.这样你就获得了资源安全.如果您稍后将对象所有权交给父母,QObject您可以使用std::unique_ptr::release(),如下所示:

auto obj = std::make_unique();
// ... do some stuff that might throw ...
QObject parentObject;
obj->setParent( &parentObject );
obj.release();

如果在给孤儿父母之前做的事情会引发异常,那么如果使用原始指针来保存对象,则会发生内存泄漏.但上面的代码可以防止这种泄漏.

更一般地说

现代C++建议不是一起避免原始指针,而是避免拥有原始指针.我可能会添加另一个现代C++建议:不要将智能指针用于其他程序实体所拥有的对象.


是.这个.所有权就是一切.我希望Qt文档对此更加明确; 似乎有很多关于儿童被"自动删除"的提法,但没有关于如何处理孤儿的大量信息.

3> Sombrero Chi..:

你已经回答了自己的问题:except if it's for historic reasons/backward compatibility.像QT一样庞大的库不能假设使用该库的每个人都有支持C++ 11的编译器.newdelete保证存在于早期标准中.

但是,如果您确实支持使用智能指针,我会鼓励在原始指针上使用它们.


错误...当qt和其他一些库被设计\实现c ++甚至没有标准的字符串类.
没有好的标准化的,但是一些基于Qt的,例如`QSharedPointer`和`QScopedPointer`.

4> PRIME..:

除了@Jamey所说的:

如果巧妙地设计它,您可能永远不必在窗口小部件上使用删除.假设您有一个主窗口,并且您正在创建它的自动对象并在事件循环中运行该窗口.现在,可以将此窗口小部件中的所有项目添加为其子项.因为您将它们作为子项直接/间接地添加到此MainWindow中,所以当您关闭此主窗口时,所有内容都将自动处理.只需要确保您创建的所有动态对象/小部件都是MainWindow的子/孙.因此无需显式删除..


你必须在创建它时立即将每个孩子添加到主窗口,或者至少在任何可以抛出的东西之前,或者事物不起作用,我想要避免记住的约束
@Martin通常没有投入任何Qt应用程序(除非一个真正的粉丝,那就是),所以来吧:)

5> g24l..:

QObject 已定义父级,程序的树状结构允许非常有效地管理内存.

Qt中的动态打破了这个不错的理想,例如传递原始指针.人们可以很容易地拿到一个dangling pointer,但这是编程中的一个常见问题.

Qt智能指针实际上是一个弱引用,它QPointer
提供了一些STL糖果.

也可以混合std::unique_ptr等,但它应该只用于程序中的非Qt机器.

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有