Qt源碼中的設計模式:對象樹機制與組合模式

對象樹與組合模式的關系

Qt 的對象樹機制是組合模式的一種實現(xiàn)崔兴,它使用了組合模式的思想來管理對象的父子關系哄褒。在 Qt 中,每個對象都可以有一個父對象棺禾,也可以有多個子對象。當一個對象的父對象被銷毀時峭跳,它的子對象也會被銷毀膘婶。這種父子關系的管理方式就是組合模式的一種實現(xiàn)方式。

使用 Qt 的對象樹機制可以非常方便地實現(xiàn)組合模式蛀醉,我們只需要在創(chuàng)建對象時悬襟,將其父對象作為構(gòu)造函數(shù)的一個參數(shù)傳遞進去,就可以自動建立父子關系拯刁。在銷毀對象時脊岳,我們只需要銷毀根對象,就可以自動銷毀其所有的子對象垛玻。這種自動管理父子關系的方式割捅,不僅可以讓代碼更簡潔,而且可以避免出現(xiàn)內(nèi)存泄漏等問題帚桩。

組合模式UML類圖

程序示例

#include <QObject>
#include <QDebug>

// 抽象組件類
class Component : public QObject {
    Q_OBJECT
public:
    explicit Component(QObject *parent = nullptr) : QObject(parent) {}
    virtual void operation() = 0;
};

// 葉子節(jié)點類
class Leaf : public Component {
public:
    explicit Leaf(QObject *parent = nullptr) : Component(parent) {}
    void operation() override { qDebug() << "Leaf operation."; }
};

// 容器節(jié)點類
class Composite : public Component {
public:
    explicit Composite(QObject *parent = nullptr) : Component(parent) {}
    void operation() override {
        qDebug() << "Composite operation.";
        for (QObject *child : children()) {
            Component *component = qobject_cast<Component*>(child);
            if (component) {
                component->operation();
            }
        }
    }
};

int main() {
    Composite *root = new Composite();
    Composite *composite1 = new Composite(root);
    Composite *composite2 = new Composite(root);
    Leaf *leaf1 = new Leaf(composite1);
    Leaf *leaf2 = new Leaf(composite1);
    Leaf *leaf3 = new Leaf(composite2);

    /*
    composite1->setParent(root);
    composite2->setParent(root);
    leaf1->setParent(composite1);
    leaf2->setParent(composite1);
    leaf3->setParent(composite2);
    */

    root->operation();

    delete root;
    return 0;
}

不多bb亿驾,直接給出一個程序示例≌撕浚可以看到莫瞬,這里并沒有實現(xiàn)UML類圖中說到的addremove方法儡蔓,因為Qt已經(jīng)內(nèi)部幫你實現(xiàn)了。在構(gòu)造函數(shù)中疼邀,將父對象傳入喂江,相當于就是調(diào)用了add方法,將自身設置為子節(jié)點旁振。

注釋塊中获询,可以看到子節(jié)點調(diào)用了setParent方法,去設置父節(jié)點拐袜。這和標準的組合模式中的父節(jié)點調(diào)用add方法筐付,將子節(jié)點加入到子節(jié)點列表,實際上是一樣的阻肿。如果將nullptr傳入setParent方法,相當于取消父子節(jié)點關系沮尿,其實和標準的組合模式中的remove方法是一樣的丛塌。在這里,我們不需要顯式的調(diào)用setParent方法畜疾,因為在上面的構(gòu)造函數(shù)中已經(jīng)傳入了各自的父節(jié)點赴邻,因此可以注釋掉。

QObject中的children方法啡捶,可以獲取所有的子對象(子節(jié)點)姥敛。程序示例中,operation方法獲取了所有的子對象瞎暑,并調(diào)用子對象的operation方法彤敛。子對象中的operation方法一樣會進行這個過程,不斷傳遞直到最終的葉子對象(沒有子對象的節(jié)點)了赌。當QObject銷毀時墨榄,其實也會發(fā)生類似的過程,從而讓所有的子對象都銷毀勿她,實現(xiàn)自動的內(nèi)存管理袄秩。

總結(jié)

其實沒什么好說的,如果熟悉Qt開發(fā)逢并,就會覺得本文講的東西太膚淺了之剧。確實,設計模式就是在日常的開發(fā)中總結(jié)和凝練出來的套路砍聊,對于有經(jīng)驗的程序員來說背稼,雖然不一定知道其概念,但是已經(jīng)在日常開發(fā)看到甚至已經(jīng)主動的去使用了辩恼。不過系統(tǒng)的定義好這些設計模式的具體概念雇庙,能夠讓我們從更宏觀的層面認識設計模式谓形,提高架構(gòu)能力。退一萬步疆前,至少能提高程序員之間的溝通效率寒跳,還是很有裨益的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末竹椒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子胸完,更是在濱河造成了極大的恐慌爆惧,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡钾军,警方通過查閱死者的電腦和手機巧颈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門蛆封,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惨篱,“玉大人琢融,你說我怎么就攤上這事漾抬⊥燔” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵性湿,是天一觀的道長。 經(jīng)常有香客問我着裹,道長骇扇,這世上最難降的妖魔是什么少孝? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮婿脸,結(jié)果婚禮上鸿脓,老公的妹妹穿的比我還像新娘在塔。我一直安慰自己幻件,他們只是感情好,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布心俗。 她就那樣靜靜地躺著傲武,像睡著了一般。 火紅的嫁衣襯著肌膚如雪城榛。 梳的紋絲不亂的頭發(fā)上揪利,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音狠持,去河邊找鬼疟位。 笑死,一個胖子當著我的面吹牛喘垂,可吹牛的內(nèi)容都是我干的甜刻。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼正勒,長吁一口氣:“原來是場噩夢啊……” “哼得院!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起章贞,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤祥绞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后鸭限,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜕径,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年败京,在試婚紗的時候發(fā)現(xiàn)自己被綠了兜喻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡赡麦,死狀恐怖朴皆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泛粹,我是刑警寧澤车荔,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站戚扳,受9級特大地震影響忧便,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一珠增、第九天 我趴在偏房一處隱蔽的房頂上張望超歌。 院中可真熱鬧,春花似錦蒂教、人聲如沸巍举。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽懊悯。三九已至,卻和暖如春梦皮,著一層夾襖步出監(jiān)牢的瞬間炭分,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工剑肯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捧毛,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓让网,卻偏偏與公主長得像呀忧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子溃睹,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 我們知道地球和一些其他行星圍繞著太陽旋轉(zhuǎn)而账,也知道在一個原子中,有許多電子圍繞著原子核旋轉(zhuǎn)因篇。我曾經(jīng)想象福扬,我們的太陽系...
    yufawu閱讀 781評論 0 4
  • 引 我們知道地球和一些其他行星圍繞著太陽旋轉(zhuǎn),也知道在一個原子中惜犀,有許多電子圍繞著原子核旋轉(zhuǎn)。我曾經(jīng)想象狠裹,我們的太...
    27億光年中的小小塵埃閱讀 69評論 0 0
  • 引自:https://blog.51cto.com/9291927/2070398 Qt高級——Qt信號槽機制源碼...
    Magic11閱讀 4,012評論 1 12
  • 組合模式 組合模式虽界,將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu),組合模式使得用戶對單個對象和組合對象的使用...
    Binaryify閱讀 468評論 0 0
  • 7 組合模式 組合模式就是用小的子對象來構(gòu)建更大的對象涛菠,而這些小的子對象本身也許是由更小的“孫對象”構(gòu)成的莉御; 7....
    Haleng閱讀 273評論 0 0