本文主要是介绍Qt 之对象树与所有权,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
作者: 一去、二三里
个人微信号: iwaleon
微信公众号: 高效程序员
QObjects在一个对象树中组织他们自己。当创建一个QObject时,如果使用了其他对象作为其父对象,那么,它就会被添加到父对象的children()列表中。这样一来,当父对象被销毁时,这个QObject也会被销毁。事实表明,这个机制非常适合于管理GUI对象。例如:一个QShortcut(键盘快捷键)对象是相关窗口的一个子对象,所以,当用户关闭了这个窗口时,快捷键也会被销毁。
详细描述
QQuickItem是Qt Quick模块的基本视觉元素,从QObject继承。但有一个不同于QObject parent的visual parent的概念,一个item的visual parent不一定和它的object parent相同。可以参考助手中的Concepts - Visual Parent in Qt Quick获取更多信息。
QWidget是Qt Widgets模块的基本类,扩展了父-子关系。孩子通常成为一个部件,即:它会显示在其父窗体的坐标系统中,并且由其父窗体的边界灵活地进行剪裁。例如:当应用程序在关闭提示框(QMessageBox)之后要删除它时,消息框的按钮和标签也会被删除。这正是我们所期望的,因为按钮和标签是对话框的子部件。
当然,也可以自己删除子对象,他们会从父窗体中移除自己。例如:当用户移除一个工具栏时,它可能会导致应用程序删除QToolBar中的一个对象,在这种情况下,工具栏的QMainWindow父窗体将会检测变化,并重新配置其相应的屏幕空间。
当一个应用程序看上去或执行起来比较奇怪时,调试函数QObject:dumpObjectTree()和QObject::dumpObjectInfo()通常比较有用。
QObjects的构造/销毁顺序
当QObjects被创建在堆上(例如:使用new创建)时,他们可以用任何顺序构造一个树。之后,树中的对象可以用任何顺序被销毁。当树中的任何QObject被删除时,如果它有父对象,析构函数会自动从其父对象中把它删除。如果它有子对象,析构函数会自动删除它的每一个子对象。无论销毁的顺序是什么,QObject都不会被删除两次,
当QObject被创建在栈上时,同样的行为适用。通常情况下,销毁顺序仍然不会出现问题。看下面的代码:
int main()
{QWidget window;QPushButton quit("Quit", &window);...
}
父窗口(window)和子部件(quit)都属于QObjects,因为QPushButton继承自QWidget,而QWidget继承自QObject。这段代码是正确的:quit的析构函数不会被调用两次,因为C++语言标准(ISO/IEC 14882:2003)指定本地对象的析构函数以和构造函数相反的顺序被调用。所以,子部件quit的析构函数首先被调用,在window调用析构之前,它已经从其父窗口window中删除自身。
如果我们交换顺序,如下所示:
int main()
{QPushButton quit("Quit");QWidget window;quit.setParent(&window);...
}
在这种情况下,销毁的顺序会引起一个问题。父窗体的析构函数首先被调用,因为它最后被创建。然后调用子部件(quit)的析构函数,这是不正确的,因为quit是一个局部变量,当出了作用域后,其析构函数再次被调用,因此会出错。
这篇关于Qt 之对象树与所有权的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!