对象树和所有权(Object Trees & Ownership )

本文介绍了Qt中的对象树概念,强调了QObject的父子关系及其在内存管理中的作用。QQuickItem和QWidget的视觉父级与对象父级之间的区别被提及。当对象被删除时,其子对象会自动删除,而析构顺序对于堆栈上的对象尤其关键,错误的构造顺序可能导致资源泄漏。同时,使用QObject的调试工具dumpObjectTree()和dumpObjectInfo()有助于排查问题。
摘要由CSDN通过智能技术生成

总览
QObject将自己组织在对象树中。当您创建一个以另一个对象作为父对象的QObject时,它将被添加到父对象的children()列表中,并在父对象被删除时被删除。事实证明,这种方法非常适合GUI对象的需求。例如,QShortcut(键盘快捷方式)是相关窗口的子级,因此,当用户关闭该窗口时,快捷方式也会被删除。
QQuickItem是Qt Quick模块的基本视觉元素,它继承自QObject,但是其视觉父级的概念与QObject父级的不同。项的视觉父项不一定与它的对象父项相同。有关更多详细信息,请参见Qt Quick中的Concepts-Visual Parent。
QWidget是Qt Widgets模块的基本类,它扩展了父子关系。通常,子级也将成为子级小部件,即在其父级的坐标系中显示,并通过其父级的边界以图形方式进行裁剪。例如,当应用程序在关闭后删除消息框时,消息框的按钮和标签也会被删除,就像我们想要的那样,因为按钮和标签是消息框的子级。
您也可以自己删除子对象,它们将从自己的父母中删除。例如,当用户删除工具栏时,它可能导致应用程序删除其QToolBar对象之一,在这种情况下,工具栏的QMainWindow父级将检测到更改并相应地重新配置其屏幕空间。
当应用程序外观或行为异常时,调试功能QObject :: dumpObjectTree()和QObject :: dumpObjectInfo()通常很有用。
QObject的构建/销毁顺序
在堆上创建QObject时(即用new创建),可以以任何顺序从它们构造树,然后,可以以任何顺序销毁树中的对象。删除树中的任何QObject时,如果对象具有父对象,则析构函数会自动从其父对象中删除该对象。如果对象有子对象,则析构函数会自动删除每个子对象。不管销毁顺序如何,都不会两次删除QObject。
在堆栈上创建QObject时,将应用相同的行为。通常,销毁顺序仍然不会出现问题。考虑以下代码段:


  int main()
  {
      QWidget window;
      QPushButton quit("Quit", &window);
      ...
  }

父窗口和子窗口都是QObject,因为QPushButton继承了QWidget,而QWidget继承了QObject。这段代码是正确的:quit的析构函数不会被调用两次,因为C ++语言标准(ISO / IEC 14882:2003)指定以与构造函数相反的顺序调用本地对象的析构函数。因此,首先调用子项的析构函数quit,然后在调用window的析构函数之前将其从其父窗口中删除。
但是现在考虑一下,如果我们交换构造顺序会发生什么,如第二个片段所示:  i

int main()
  {
      QPushButton quit("Quit");
      QWidget window;

      quit.setParent(&window);
      ...
  }

在这种情况下,破坏顺序会引起问题。首先调用父级的析构函数,因为它是最后创建的。然后,它将调用其子项的析构函数quit,这是不正确的,因为quit是局部变量。当退出随后超出范围时,它的析构函数将再次被调用,这一次是正确的,但是损害已经造成。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道格拉斯范朋克

播种花生牛奶自留田

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值