Qt对象树和QObject的构建/销毁顺序

Qt使用对象树组织QObject

当以一个对象作为父对象创建QObject时,这个对象就会被添加到父对象的children()列表中,当父对象被delete时该对象也会被释放。

在析构一个对象obj时,会进行两个操作:

  • 如果它有parent,它会从它的parent中移除。
  • 如果它有children,它的所有children会自动delete。

记住,QT主要用来开发图形用户界面程序。这种对象的组织方法非常适合GUI对象的需求,

例如,QShortcut(键盘快捷方式)是相关窗口的子级,当用户关闭该窗口时,该快捷键也会被删除。

不仅如此,QWidget作为Qt Widgets模块的基本类(所有用户界面对象的基类),它还扩展了QObject的父子关系。
一个QWidget的子级成为了子级小部件,它在其父级的坐标系中显示,并根据其父级的边界以图形方式进行裁剪

例如,当应用程序在关闭后删除消息框时,消息框的按钮和标签也会被删除,因为按钮和标签是消息框的子级。

QObject的构建/销毁顺序

根据对象创建方式需要分为两种情况来讨论:

1.在堆上创建(使用new创建)

当在堆上创建QObject时(即用new创建),可以以任何顺序创建对象、构造对象树。也可以以任何顺序销毁树中的对象。

2.在栈上创建

在栈上创建QObject时,通常销毁顺序仍然不会出现问题。
看下面这个例子:

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

quitwindow的子对象。根据C++语言标准,以与构造函数相反的顺序调用本地对象的析构函数,那么在程序结束时,quit的析构函数将会先被调用,它将自己从其父对象中移除。随后,window的析构函数被调用,由于quit已从window的children中移除,quit的析构函数不会被调用两次。销毁正常。


需要注意的是这种情况:

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

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

根据创建顺序,window会先被析构,它也将调用它的所有children的析构函数,即quit的析构函数会在此时被调用。随后,quit这个局部变量的析构函数会再一次被调用,也就是说quit的析构函数调用了两次。
在这种情况下,销毁顺序出现了问题。因此,在编码时需要注意对象的创建顺序,最好按照父先子后的顺序进行创建。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值