QObject 是 Qt 庫中許多重要類的基類,如 QEvent,Qapplication 和 QWidget 等。我們會將任何從 QObject 類派生出的對象看做是一個 QObject 對象。它可以使用信號和槽與其他 QObject 通信。 每個 QObject 都可以有(至多)一個父 QObject,和任意數量的子 QObject 。每個 QObject 都有一條 QObjectList 的列表,里面存放的是各個子對象的指針。 每個 QObject 父對象都會管理自己的子對象。這就意味著,在調用父對象析構函數時也會調用子對象的析構函數。 給某個對象設置父對象,就會隱含地將此對象的指針添加到父對象的子對象列表中,例如:objA->setparent(objB);
。 如果隨后再運行objA->setparent(objC);
,那么 objA 的指針就會從 objB 的子對象列表中移除,然后添加到 objC 的子對象列表中。這一操作被稱為重新父化
注意: 通常而言,沒有父對象的 QObject 對象需要在程序棧區中進行定義,而那些有父對象的 QObject 則可以在堆區動態創建出來。原因:位于棧區的對象在超出作用域時,就會被銷毀,而它的子對象也會隨著銷毀。
C++ 類型可以分成兩類:值類型和對象類型。 值類型的實例通常相對簡單,占用相鄰的內存空間,而且可以進行快速復制或者比較。值類型的例子有:int,char,QString,QDate 和 QVariant。 QVariant 是一種特殊的聯合體類型,可保存所有可復制的內置類型和編程人員自定義的類型。
提示: 盡量不要在堆區創建 QList ,QString,QImage 或者其它和 QVariant 相關的類型。原因1:Qt已經為你完成了引用計數和內存管理。其它原因不明。
組合模式的意圖是通過將【部分——整體】的層次結構表示成樹形結構,以便于使用較為簡單的部分創建出復雜的對象。 這幅圖主功能的每一個矩形框都是一個組件,它可能是一個復合組件并擁有一定數量子組件,也可能其中的僅僅是一個單獨的組件。最后通過組件對應的一個個枝葉就可以匯聚成一顆完整的樹。 如果要表達這所大學的架構可以使用組合模式來對這所大學進行建模。樹中的每一個節點使用下面的類的對象進行表示。
通過 QObject 的公有接口,可以構建一顆類似于樹的表達方式來描述這所大學的組織結構,然后實例化一個 OrgUit 并調用 setParent 函數將其添加到合適對象的子對象列表中。
下面的函數用于計算學校對應部分的工資總和。
double OrgUnit::GetSalary(){ QList<OrgUnit*> childList = findChildren<OrgUnit*>(); double salaryTotal(salary_); if (!childList.isEmpty()) { foreach (OrgUnit* ougPtr, childList) salaryTotal += ougPtr->GetSalary(); } return salaryTotal;}可以從任意特定的節點調用 GetSalary 方法,返回的結果是以此節點為根的樹所對應大學中相應部門的工資總和。例如:如果 ougPtr 指向 University,那么 GetSalary 會返回的是整個大學的總工資;如果指向的是 EnglishDpt ,那么 GetSalary 會返回的是英語系的總工資。 推薦閱讀:C++設計模式——組合模式
每個 QObject 都可以擁有任意數量的 QObject 子對象。這些子對象的地址會存在一個特殊的 QObject 指針容器內。QObject 有一個成員函數,可以返回一個指向父對象中全部子對象的指針列表。這個函數的原型是: const QObjectList& QObject::chidren()const
QObject還提供兩個函數
T QObject::findChild (const QString & name = QString()) const
,返回一個子對象QList<T> QObject::findChildren(const QString & name = QString()) const
該函數返回一個類型為T的子對象列表。更詳細的參考:Qt之findChild以下為一個演示
class Person : public QObject{public: explicit Person(QString name, QObject *parent = 0); virtual ~Person();};Person::Person(QString name, QObject *parent) :QObject(parent){ setObjectName(name); cout << QString("Constructing Person: %1").arg(name)<< endl;}Person::~Person(){ cout << QString("Destroying Person: %1").arg(objectName()) <<endl;}void growBunch(){ qDebug("First we create a bunch of object."); QObject bunch; Person* mike = new Person("Mike",&bunch); Person* carol = new Person("Carol",&bunch); new Person("Greg",mike); new Person("Bobby",carol); Person* child = bunch.findChild<Person* >("Mike"); cout << child << "/t" << mike << endl; Person* alice = new Person("Alice",&bunch); cout << &bunch << "/t" << alice->parent() << endl; bunch.dumpObjectTree(); return ;}int main(int argc, char *argv[]){ growBunch(); return 0;}新聞熱點
疑難解答