前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >看Qt源码理解为什么布局类不用删除?

看Qt源码理解为什么布局类不用删除?

作者头像
Qt君
发布2020-06-24 15:35:42
8990
发布2020-06-24 15:35:42
举报
文章被收录于专栏:跟Qt君学编程跟Qt君学编程

我们不妨看看以下小例子。

代码语言:javascript
复制
QWidget window;
QPushButton *button1 = new QPushButton("One");
QPushButton *button2 = new QPushButton("Two");
QPushButton *button3 = new QPushButton("Three");

QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);

window.setLayout(layout);
window.show();

qDebug() << "Window children:" << window.children();

  可以看到QPushButton和QHBoxLayout控件在new完后不需要执行delete操作。究竟是为何呢?我们再看看打印输出:

代码语言:javascript
复制
Window children: (QHBoxLayout(0x1f32ebc0), QPushButton(0x1f48ea00), QPushButton(0x1f48e9c0), QPushButton(0x1f48e580))

  打印输出可以看到window对象下有QHBoLayout和3个QPushButton子控件,意味着当window对象析构时会先析构其下的所有子控件,所以就不需要手动删除了。

为了进一步验证,君君为大家奉上其Qt的实现源码。

  QWidget的setLayout源码中可以看到布局控件(QLayout)对象最终会设置自己的父类为QWidget。

代码语言:javascript
复制
/* 省略部分无关代码 */
void QWidget::setLayout(QLayout *l)
{
    ...
    if (oldParent != this) {
        l->setParent(this);
        l->d_func()->reparentChildWidgets(this);
        l->invalidate();
    }
}

  QLayout的addWidget内部实现是传入的w对象最终也会设置其QLayout的parentWidget()对象。

代码语言:javascript
复制
void QLayout::addWidget(QWidget *w)
{
    addChildWidget(w);
    addItem(QLayoutPrivate::createWidgetItem(this, w));
}

void QLayout::addChildWidget(QWidget *w)
{
    QWidget *mw = parentWidget();
    QWidget *pw = w->parentWidget();

    ...
    if (!pw && mw)
        w->setParent(mw);
    ...
}

  最后经过一轮花里胡哨的操作,最后QHBoxLayout和QPushButton控件都有一个共同的父类就是window

相关知识

  在Qt中,每个QObject内部都有用来保存所有的子对象列表(children),同时还会保存自己的父对象(parent)。当它自己析构时,它会将自己从父对象(parent)的列表中删除,并且析构掉所有的子对象列表(children)。

看Qt源码理解半自动内存管理

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Qt君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 相关知识
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档