關聯,C++使用指針實現,兩者到關系最弱,並且可以兩向關聯,B* A::b 與 A* B::a 可以並存,兩者間沒有明確的ownership關系,為什么不是引用,因為引用沒有辦法實現相向引用,這會是一個蛋和雞誰先的問題,A, B對象的引用類型的成員都必須要求在構造時初始化,那么兩者到底誰先來后到呢? i maybe know you, but i never need to own you.
聚合,C++使用引用實現,兩者(對象)間只能確定一種引用關系,與整體與部分的關系唯一確定一致,B& A::b 與 A& B::a 不並存,以B& A::b為例,A在構造時必須要確定b成員的引用,也就是必須有一個B對象先於A對象構造,A對象構造是確定對B對象的聚合關系。這樣那契合聚合的關系比聯強。但是由於C++不是gc管理對象回收的語言,所以必須要確保聚合的一方的生命周期不可以超過被聚合的一方。同樣以 B& A::b (A聚合B)為例。A對象的生命周期不可以超過B對象的生命周期,如果B對象是一個Local對象,A對象的作用域也離不開B對象的作用域,要是B對象是一個Heap對象,就要小心管理B對象的生命周期,不要讓A的生命周期超過它。i need you,but i do not own you.
組合,C++使用成員變量。構造時同構造,析構時同析構。被組合方不是來自整體的外部,整體對部分有ownership。i have you and strongly own you.
從生命周期來看,關聯時大家的生命周期大家都管不着,聚合時部分的生命周期長於整體,組合時整體與部分共存亡(整體的生命周期比部分略長一點)。
上面的實現不是硬性的,只是比較好的契合語言的特點,或者說通常下比較直觀的實現方式。如果全部用指針來做,例如組合,構造時new成員,析構時delete成員,又或者成員不是在構造時創建,需要在OnInit時才能創建,這樣一來就得使用指針,但也不因為用了指針就影響了整體對部分的ownership,兩者就馬上下降為關聯了。使用指針來實現組合關系,自己就得要按組合的約束做多一點功夫進行約束,確保組合的關系不走樣。