[QT] 2022.4.28 对象树

目录 

GUI

QPushButton类的操作示范:

对象树

——对象树案例

——特殊情况


GUI

GUI(graphical user interface): 图形用户接口 (界面)

指一种以图形为基础的人机交互模式。

与通常的命令符或文本控制不同。gui的界面使用户看到的都是标准化、人性化的图形对象,用户只需要通过一个个窗口就可以凭借常识完成自己希望的操作。

——————————————————————————————————

QPushButton类的操作示范:

    QPushButton *window1  = new QPushButton;    //两种初始化方式
    window1->setParent(this);
    window1->setText("保存");
    QPushButton *window2 = new QPushButton("关闭",this);

    window1->move(0,0);         //按钮设置
    window1->resize(60,30);
    window2->move(60,0);
    window2->resize(60,30);

    setFixedSize(300,300); //固定高度
    setWindowTitle("窗口名称是什么");  //窗口栏名称

    window1->show();
    window2->show();
    myPushButton *window3 = new myPushButton;
    window3->setText("myPushButton");
    window3->setParent(this);  //这里的parent 和继承的父类
    window3->move(120,0);
    window3->resize(90,30);
    window3->show();
    // window3 可以看出只要指定了对象树(这里其父是mywindow)就不需

——————————————————————————————

 

 

对象树

对象树的作用在我们创建对象时的parent指针可以看出。可以把这棵树看成一个家谱,把不同类的长幼关系安排清楚。

QObject类 的对象创造时,会在构造函数时接收一个parent指针作为参数,即父对象指针。

如以QObject为基类的对象树组织起来,当QObject被释放,它的所有子类(即直接或间接的 setparent(QObject) 对象 )都会被自动释放。

但这仅仅是从功能上而言。本质上 父子对象 和 C++正常继承的父类子类关系 没有任何联系。

对象树案例

自己创建一个按钮类:myPushButton 来试验对象树释放的特性

这里的 myPushButton 是以 QWidget 为基类的

mypushbutton.cpp

#include "mypushbutton.h"
#include<QDebug> //宏,返回临时对象
    //指针不必要改成父类 是因为其父类QPBt的参数指针同样是 QWidget类型   //相当于在"一串"对象树上
myPushButton::myPushButton(QWidget *parent) : QPushButton(parent) 
{                       //parent交给父类构造。其父类QPBt默认构造为有参,需要传参数完成对象树构建
    qDebug("myPusButton 构造");
};

myPushButton::~myPushButton()
{
    qDebug("myPushButton 析构");
    //先打印,不释放,逐层向下观察
}

 mypushbutton.h 包含 QPushButton头文件

创建对象在堆区,而该对象已指定好了父亲(setParent),只要把其父辈释放析构,接下来的字辈会随之释放。有智能指针的感觉,像监护人一样。这样在一定程度上简化了内存回收机制。

当然,你可以自己手动删除某个子类,它和它下面的一系列子类会自动从父类的析构名单中消失。

特殊情况

刚刚一直在聊堆区析构,下面来探索一下栈区析构。

    mywindow w;
    QPushButton p("Button1",&w);

正常栈区创建,mywindow和QPB都是 QObject 的子类;

由C++的特性可知,析构顺序与他们的构造顺序相反

此时换一个构造顺序 

     QPushButton p("Button1");

     mywindow w;

     p.setParent(&w);     

我们发现程序异常结束了—— 作为父指针的mywindow后创建,先析构;可由于对象树特性,mywindow会调用每一个子指针的析构函数,所以在mywindow析构过程中,p已经析构了。

那么mywindow析构结束,p先创建,还是要在最后析构,这样就析构了两次。

所以这就不难理解为什么出现问题了。

由这个特殊情况,我们总结:①构造对象时便指定好父对象(parent指针) ② 大胆在堆上创建对象

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值