zoukankan      html  css  js  c++  java
  • Qt 对象间的父子关系

    C++中只要有一个new就必须要有一个delete与之对应

    但是Qt中的对象之间有特殊的关系

    Qt 对象间的父子关系

    每一个对象都保存有它所有子对象的指针

    每一个对象都有一个指向其父对象的指针

    parent里面有个链表 链表的每一个元素都是就是指向子对象的 指针

      类似的每一个子对向都保存了一个指向父对象的指针

    Qt中的对象如何指定其父对象?

    成员函数:setparent;

     当调用setparent函数时,父对象将子对像加入到自己的链表中,子对像将一个指针指向父对象,这样对象就产生了父子关系。

    为证明上述新建一个控制台的应用程序

      

    #include <QCoreApplication>
    #include <QDebug>
    void fcTest()
    {
        QObject* p = new QObject();
        QObject* c1 = new QObject();
        QObject* c2 = new QObject();
    
        c1->setParent(p);//该函数执行后p执行那个的对象就变成了父类的对象
        c2->setParent(p);
    
        qDebug() << "c1: " << c1;//输出c1对象的地址
        qDebug() << "c2: " << c2;
    
        const QObjectList& list = p->children();
    
        for(int i=0; i<list.length(); i++)//Qt中提供了想访问数组的方式访问这个链表
        {
            qDebug() << list[i];
        }
    
        qDebug() << "p: " << p;
    
        qDebug() << "c1 parent: " << c1->parent();//函数返回父对象的指针
        qDebug() << "c2 parent: " << c2->parent();
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        fcTest();
        return a.exec();
    }
    

     如果对代码中的成员函数不理解可以到Qt的帮助文档中直接找其说明

    方法:1、搜索QObject类

            2、在该类的成员函数中找对应的函数了即可得到该函数的说明:Makes the object a child of parent.即指定一个对象的父类。

    对于const QObjectList& list = p->children();同样使用上面Qt中的文档找到:

    const QObjectList & QObject::​children() const

    Returns a list of child objects. The QObjectList class is defined in the <QObject> header file as the following:

     typedef QList<QObject*> QObjectList;

    可以知道该函数的返回值const QObjectList &类型的链表

    其中QObjectList 又是一个 QList<QObject*>  即是一个链表,链表中的元素又是QObject对象类型指针

     

    Qt对象销毁时又会有那些事情?

    当Qt对象被销毁时,很有可能不止一个对象被销毁,因为其销毁时,会将该对象的子对象链表中的所有对象都销毁。

     通过setparent就可以形成上面的对象数,当删除obj3时,其子类obj4的对象也要会销毁。

    为证明上面的结论:

    创建一个继承QObject的类

     1 class MObj:public QObject
     2  {
     3 
     4     QString m_name;
     5  public:
     6      MObj(const QString& name)
     7     {
     8         m_name=name;
     9         qDebug()<<"Constructor:"<<m_name;
    10       }
    11 
    12      ~MObj()
    13      {
    14      qDebug() << "Destructor: " << m_name;
    15     }
    16  };

    测试函数:

     void delTest()
     {
         MObj* obj1=new MObj("obj1");
        MObj* obj2=new MObj("obj2");
         MObj* obj3=new MObj("obj3");
         MObj* obj4=new MObj("obj4");
        //构建对象数
         obj2->setParent(obj1);
         obj3->setParent(obj1);
         obj4->setParent(obj3);
     
         //删除obj3
         delete obj3;
       
     //delete obj4;如果再次delete obj4就会出错,
        //由于obj4已经被delete了,此时obj4是一个野指针,delete野指针肯定会内存出错的
     }

    完整代码:

     1 #include <QCoreApplication>
     2 #include <QDebug>
     3 #include <QString>
     4 
     5 class MObj:public QObject
     6  {
     7     
     8     QString m_name;
     9  public:
    10      MObj(const QString& name)
    11     {
    12         m_name=name;
    13         qDebug()<<"Constructor:"<<m_name;
    14       }
    15      ~MObj()
    16      {
    17      qDebug() << "Destructor: " << m_name;
    18     }
    19  };
    20 void delTest()
    21 {
    22     MObj* obj1=new MObj("obj1");
    23     MObj* obj2=new MObj("obj2");
    24     MObj* obj3=new MObj("obj3");
    25     MObj* obj4=new MObj("obj4");
    26     //构建对象数
    27     obj2->setParent(obj1);
    28     obj3->setParent(obj1);
    29     obj4->setParent(obj3);
    30     //删除obj3
    31     delete obj3;
    32 }
    33 int main(int argc, char *argv[])
    34 {
    35     QCoreApplication a(argc, argv);
    36     delTest();
    37     return a.exec();
    38 }
    View Code

    结果:

    可以看到析构函数被调用了两次,包括obj4和obj3

    小结:

     学习狄泰软件Qt实验教程学习笔记16课 

  • 相关阅读:
    云时代架构读后感
    余额宝技术架构读后感
    shiyan
    11111
    编写hdfs文件遇到的问题
    123
    啦啦啦
    Hadoop安装
    js根据银行卡号进行判断属于哪个银行并返回银行卡类型
    git 使用
  • 原文地址:https://www.cnblogs.com/zhaobinyouth/p/6262331.html
Copyright © 2011-2022 走看看