2012-12-16 33 views
3

用C++思考卷。 1(P-33):成員對象如何在運行時更改組合?

組成自帶的靈活性很大。您的新課程的成員 通常都是私密的,因此他們使用該課程的客戶端程序員無法訪問其 。這 允許您更改這些成員,而不會打擾現有的 客戶端代碼。
您也可以在運行時更改成員對象,以 動態更改程序的行爲。下面介紹的繼承 不具備這種靈活性,因爲編譯器必須對帶有繼承性的創建類 的類進行編譯時限制。

我們如何在運行時改變成員對象的構圖?
寫入類聲明時不包含對象嗎?

class car
{
private:
engine obj;
}

所以,這裏的類car包含engine類的對象。我們如何在運行時改變它?

或者我錯過了一些觀點?

+0

這基本上是指向一種名爲**策略**的設計模式,如果您詳細瞭解它,您將能夠自己回答您的問題。 –

+0

啊,SO上的粗斜體字體幾乎不可讀: –

回答

6

嘗試使用的一個指針成員對象,而不是:

class car { 
    engine *obj; 
} 

現在,你可以在運行時是否使用rotary_enginev8_engineflux_capacitor_engine實例選擇。

當然,您可能想要使用類似unique_ptrshared_ptr的東西來管理成員對象的所有權和生命週期。

1

這確實有點含糊不清。

組成限定has-a關係,即car具有engine。你可以交換你的車的引擎,汽車仍然會是一輛車。

繼承定義is-a關係,即,如果你定義了汽車從發動機繼承,這將意味着carengine。更改引擎意味着汽車類型的變化 - 如果您更改基類,它會自動更改派生類。使用合成時,此限制不存在。

所以在你的例子中,構圖是正確的。

+0

請注意,這個「composition->,inheritace-> is」僅適用於Java(僅限OOP)語言。C++也可以以不同的方式使用:私有和受保護的繼承是一種組合形式(公共繼承是一個*匿名組合*,從編譯器的角度來看),並且特性類上的CRTP繼承可以用來觸發*多態組合*更不用說「 「和」有「可以用口頭形式交換:你可以*有*長髮或*爲*日誌頭髮。因此,謹慎使用這種歧視,因爲外面的世界可能並不那麼簡單 –

+0

@EmilioGaravaglia是的,我在談論的是「公共」繼承,這是唯一與構圖相比較的相關性;「protected」和「private」用於不同的設計目的。關於CRTP - 這實際上是一種技術,儘管您的評論是正確的,我指的是構成與繼承的**概念**,而不是通過各種技術實現這一或另一個的可能性。然而,你的例子在我看來是不正確的。如果你*有*長頭髮,並不意味着你*長頭髮。但這是一個不同的廣泛的設計主題,遠離這個問題 – SomeWittyUsername

+0

AH ....是的......你可以有*別人*長髮!特別是如果你從切諾基下降! (你是通過繼承來的!)除了笑話以外,儘管我不同意你的一些論斷,但我的和你的存在和工作的事實就是演示事物不能簡單地如此簡化。 –

0

對於純的組合,運行時間變化也是可能的:

class Car { 
private: 
    CarPart &get_part(int i) const { 
     switch(i) { 
      case 0: return e; 
      case 1: return w1; 
      case 2: return w2; 
      case 3: return w3; 
      case 4: return w4; 
     } 
    } 
private: 
    Engine e; 
    Wheel w1, w2, w3, w4; 
}; 

然後例如設置屬性很簡單:

void set_property(int id, std::string name, int value) { 
    CarPart &p = get_part(id); 
    p.set(name, value); 
} 

這大約是動態的,你可以得到...

相關問題