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的类

 class MObj:public QObject
{ QString m_name;
public:
MObj(const QString& name)
{
m_name=name;
qDebug()<<"Constructor:"<<m_name;
} ~MObj()
{
qDebug() << "Destructor: " << m_name;
}
};

测试函数:

 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野指针肯定会内存出错的
}

完整代码:

 #include <QCoreApplication>
#include <QDebug>
#include <QString> class MObj:public QObject
{ QString m_name;
public:
MObj(const QString& name)
{
m_name=name;
qDebug()<<"Constructor:"<<m_name;
}
~MObj()
{
qDebug() << "Destructor: " << m_name;
}
};
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;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
delTest();
return a.exec();
}

结果:

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

小结:

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

Qt 对象间的父子关系的更多相关文章

  1. 7.QT-Qt对象间的父子关系

    Qt对象之间可以存在父子关系 继承于QObject类或者其子类的对象,都称为Qt对象 当指定Qt对象的父对象时 需要通过setParent()成员函数来设置对象间的父子关系 子对象将会把自己的指针地址 ...

  2. RXJS组件间超越父子关系的相互通信

    RXJS组件间超越父子关系的相互通信 用到这个的需求是这样的: 组件A有数据变化,将变化的数据流通知组件B接收这个数据流并做相应的变化 实例化RXJS的subject对象 import { Injec ...

  3. 让两个对象间建立weak关系

    让两个对象间建立weak关系 这是为了给两个对象间建立weak关系,当一个对象被释放时,另外一个对象再获取这个值时就是nil,也就是不持有这个对象:) 源码: WeakRelatedDictionar ...

  4. 【原创】面向对象作业:选课系统中用pickle储存多个对象间组合引用关系的那些坑

    转载请注明出处:https://www.cnblogs.com/oceanicstar/p/9030121.html 想直接看结论先提前列出: 1.存储一个对象,文件不是真的给你存储的了对象这种东西, ...

  5. 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感

    关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...

  6. QT场景视图父子关系图元打印研究

    在之前的一篇文章中,实现了QT场景视图的打印功能,主要通过render函数来实现,非常简单和方便. 在实际的项目需求中,除了打印整个场景外,还需要对单个图形进行打印操作,基于item的图形可以在pai ...

  7. SQL Server 查看对象之间的引用关系

    前期准备: use studioA;           go create table T(X int,Y int); insert into T(X,Y) values(1,1),(2,2);  ...

  8. 如何才能学到Qt的精髓——信号槽之间的无关性,提供了绝佳的对象间通讯方式,QT的GUI全是自己的一套,并且完全开源,提供了一个绝好机会窥视gui具体实现

    姚冬,中老年程序员 叶韵.KY Xu.赵奋强 等人赞同 被邀请了很久了,一直在思考,今天终于下决心开始写回答. 这个问题的确是够大的,Qt的代码规模在整个开源世界里也是名列前茅的,这么大的项目其中的精 ...

  9. QT父子与QT对象delete

    原地址:http://www.qteverywhere.com/archives/437 很多C/C++初学者常犯的一个错误就是,使用malloc.new分配了一块内存却忘记释放,导致内存泄漏.Qt的 ...

随机推荐

  1. c# 如何通过反射 获取\设置属性值、

    //定义类public class MyClass{public int Property1 { get; set; }}static void Main(){MyClass tmp_Class = ...

  2. NULL, nil, Nil详解

    原文地址:http://blog.csdn.net/wzzvictory/article/details/18413519    感谢原作者 作者:wangzz 原文地址:http://blog.cs ...

  3. 从xib加载文件

    一般自定义View, 如果从xib加载文件, 定义一个类方法, 返回xib + (instancetype)dropdown { return [[[NSBundle mainBundle] load ...

  4. Android使用pull解析xml

    一.理论准备     Pull解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.跟SAX不同的是, ...

  5. DDD领域驱动设计和实践(转载)

    -->目录导航 一. DDD领域驱动设计介绍 1. 什么是领域驱动设计(DDD) 2. 领域驱动设计的特点 3. 如果不使用DDD? 4. 领域驱动设计的分层架构和构成要素 5. 事务脚本和领域 ...

  6. 【POJ 2987】Firing (最小割-最大权闭合子图)

    裁员 [问题描述] 在一个公司里,老板发现,手下的员工很多都不务正业,真正干事员工的没几个,于是老板决定大裁员,每开除一个人,同时要将其下属一并开除,如果该下属还有下属,照斩不误.给出每个人的贡献值和 ...

  7. 用js判断操作系统和浏览器类型

    判断操作系统和浏览器的js代码 navigator.userAgent:userAgent 属性是一个只读的字符串,声明了浏览器用于 HTTP 请求的用户代理头的值.    navigator.pla ...

  8. 再探CRC

    之前写了CRC16的程序,虽说能用,却不知其所心然,现在要用CRC32,重温一遍,一下就通了.笔记如下 CRC我没记错的话是Cyclic Redundancy Code,Cyclic和Redundan ...

  9. MST(prim)+树形dp-hdu-4756-Install Air Conditioning

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4756 题目意思: n-1个宿舍,1个供电站,n个位置每两个位置都有边相连,其中有一条边不能连,求n个 ...

  10. logstash date插件

    [elk@dr-mysql01 api-access]$ date Wed Nov 30 19:21:35 CST 2016 [elk@dr-mysql01 api-access]$ [elk@dr- ...