C++中的繼承、組合、聚合和關聯

本文轉載自:
http://blog.csdn.net/kkforwork/article/details/46225747

一、繼承、組合和聚合

繼承和組合是兩個完全不同的概念
繼承,表達的是“is-a”的關系,兩者之間是一種上下級的關系,比如,我們說“human is a animal“(人是動物的一種,換句話說,動物是人的上級),要表達這種關系,就可以使用繼承

calss animal
{};
class human : public animal  // 繼承
{};

組合和聚合,則是表達兩個平等對象之間整體和局部的關系,而因為這種關系的緊密性的不同,而又分為了組合和聚合。組合表達的是“contain-a”的關系,整體和局部擁有相同的生命周期,換句話說,如果整體對象不存在了,那么局部對象也會消亡。在C++中,我們通常在整體類中加入一個局部類的對象作為其成員,來表達這種組合關系(整體對象創建的同時,也會創建局部對象,而整體對象消失了,局部對象也會消失),比如,我們說“human conains a head”(人有一個腦袋,人活著,腦袋也活著,如果人死了,腦袋也就是了),

class head
{};
calss human
{
private:
    head h;  // 數據成員對象表示的組合關系
}

聚合同樣表的是整體和局部的關系,但是這種關系要松散得多,它表達的是一種“has-a”的關系,整體和局部擁有各自的生命周期,兩者可以單獨存在,相互獨立,并不像組合一樣兩者相互依存,但兩者也可以聚合在一起,形成一個新的類型。比如,我們說“human has a computer”(人有一臺電腦,電腦和人都是各自獨立的,而兩者聚合在一起,就成了“有電腦的人”),在C++中,我們通常在整體類中加入指向局部類的指針,來表達這種“聚合”關系(整體對象創建的時候,不一定有局部對象,可能已經創建,也可以還沒有,而整體對象消失了,局部對象還可以繼續存在,也可能消失,想象一下電腦和人的關系,生不帶來,死不帶去)。

calss computer
{};
class human
{
// ...
private:
    computer* pCom; // 指針表示的聚合關系
};

總結起來,繼承表達的是一種上下級的關系(is-a),聚合表達的是一種松散的整體和局部的關系(has-a),而組合表達的是一種緊密的整體局部關系(contain-a)
另外:

class A{
private:
    B* p_b;
};
A::A(){
    p_b=new B;
}
A::~A(){
    delete p_b;
}

A與B的關系是組合。雖然是用指針表示的,依然是組合關系。
到底是組合還是聚合,其實現形式(用成員還是指針)不是判斷標準,兩者生命周期的差異,才是判斷標準。兩者生命周期相同的,是組合,比如成員變量,你這里用指針的實現,而生命周期不同的,才是聚合。

二、關聯和聚合

關聯和聚合的區別主要在語義上,關聯的兩個對象之間一般是平等的,例如你是我的朋友,聚合則一般不是平等的,例如一個公司包含了很多員工,其實現上是差不多的。
聚合和組合的區別則在語義和實現上都有差別,組合的兩個對象之間其生命期有很大的關聯,被組合的對象是在組合對象創建的同時或者創建之后創建,在組合對象銷毀之前銷毀。一般來說被組合對象不能脫離組合對象獨立存在,而且也只能屬于一個組合對象,例如一個文檔的版本,必須依賴于文檔的存在,也只能屬于一個文檔。聚合則不一樣,被聚合的對象可以屬于多個聚合對象,例如一個員工可能可以屬于多個公司。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容