前言
Qt是一个流行的C++框架,用于开发跨平台的图形用户界面(GUI)应用程序。Qt提供了一种强大的对象模型,其中一个关键概念是对象间的父子关系。
一. Qt 对象可以存在父子关系:
在Qt中,对象间的父子关系是通过 QObject 类和对象树机制来实现的。每个QObject派生类都具有父子关系的能力。通过建立父子关系,可以形成一个层次结构,从而方便进行对象的管理和组织。
父子关系在Qt中有以下几个主要作用:
- 对象的内存管理:父对象负责管理其所有子对象的生命周期。当父对象被销毁时,它会自动销毁其所有子对象。这种自动释放内存的机制大大简化了对象资源的管理,减少了内存泄漏的风险。
- 信号与槽机制:父子关系对信号与槽机制的使用提供了便利。当一个对象发送信号时,其父对象可以接收并处理该信号。这种机制可以用于在对象之间进行通信和交互。
- 对象的查找和访问:通过父子关系,可以方便地查找和访问对象树中的对象。通过QObject的findChild()和findChildren()等函数,可以在对象树中根据对象名称、类型等条件查找对象,实现对象之间的联动和数据传递。
二. 父子关系的建立:
在Qt中建立父子关系很简单。可以通过在构造函数中传递父对象指针来建立对象间的父子关系,或者使用setParent( ) 函数来设置父对象。
示例代码:
QObject* parent = new QObject(); // 创建父对象
QObject* child = new QObject(parent); // 创建子对象,并指定父对象
Qobject* p = new Qobject( );
Qobject* c1 = new Qobject ();
Q0bject* c2 = new Qobject ( );
c1->setParent (p) ; // 指定父对象
c2->setParent (p);
Qt提供了几个函数来管理父子关系:
- setParent ( ) :设置对象的父对象。
- parent( ) :获取对象的父对象。
- children( ) :获取对象的直接子对象。
- findChild( ) 和 findChildren( ) :在对象树中查找对象。
当指定Qt 对象的父对象时:
- 其父对象会在子对象链表中加入该对象的指针
- 该对象会保存指向其父对象的指针
三. Qt 对象的销毁:
当父对象被销毁时,它会自动销毁其所有子对象。这种自动释放内存的机制大大简化了对象资源的管理,减少了内存泄漏的风险。
利用Qt对象间的父子关系可以构成对象树 。删除树中的节点时会导致对应的子树被销毁.
代码解析:
class My_Object : public QObject
{
QString m_name;
public:
My_Object(const QString& name)
{
m_name = name;
qDebug() << "My_Object: " << m_name;
}
~My_Object()
{
qDebug() << "~ My_Object: " << m_name;
}
};
void Test()
{
My_Object* obj1 = new My_Object("obj1");
My_Object* obj2 = new My_Object("obj2");
My_Object* obj3 = new My_Object("obj3");
My_Object* obj4 = new My_Object("obj4");
obj2->setParent(obj1);
obj3->setParent(obj1);
obj4->setParent(obj3);
delete obj3; // 销毁 obj3
const QObjectList& list = obj1->children();
qDebug() << "obj2: " << obj2;
// qDebug() << "obj3: " << obj3;
for(int i=0; i<list.length(); i++) // 便利链表
{
qDebug() << list[i];
}
// delete obj4; 销毁 obj3 后 不可重复销毁 obj4
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Test();
return a.exec();
}
销毁 obj3 后 :
链表 里 只有 obj2 的地址。
未 销毁 obj3 时:
链表 里 有 obj2 和 obj3 的地址。
总结
Qt对象间的父子关系是一种强大而便捷的机制,用于对象管理、内存释放、信号与槽机制和对象访问。通过建立父子关系,可以形成一个层次结构,简化对象的管理和组织。在使用父子关系时,需要注意对象的生命周期和内存管理,以确保正确且安全地使用这一特性。