2014-01-12 64 views
0

在子類中,我需要複製基類中的字段。一個簡單的例子:如果我們有一個基類Car,我想製作一輛名爲DoubleCar的汽車,它代表兩輛車中的一輛(有兩個引擎,八個車輪等)。這個DoubleCar就像一輛汽車(我們可以啓動它,加速,剎車等等),所以繼承似乎很自然。我嘗試做它通過以下方式如何從基類C++複製字段

class Engine{ 
    public: void Start(){} 
}; 
class Car 
{ 
    Engine* engine; 
public: 
    Car(Engine* engine){this->engine=engine;} 
    virtual void Start(){engine->Start();} 
}; 

,創造DoubleCar擁有的第一輛車從基類和secondCar爲現場:

class DoubleCar : public Car 
{ 
    Car* secondCar; 
public: 
    DoubleCar(Engine* e1, Engine* e2) : Car(e1) 
    {secondCar = new Car(e2);} 
    virtual void Start(){Car::Start(); secondCar->Start();} 
}; 

該解決方案看起來醜陋,它看起來像一個汽車比另一個更重要。我也試圖把兩輛車都放在田裏,而忽略底座成員,像這樣

class DoubleCar1 : public Car 
{ 
    Car *firstCar, *secondCar; 
public: 
    DoubleCar1(Engine* e1, Engine* e2) : Car(NULL) 
    {firstCar = new Car(e1); secondCar = new Car(e2);} 
    virtual void Start(){firstCar->Start(); secondCar->Start();} 
}; 

這也不是一個好的解決方案。對於這樣的問題,什麼是一個好的設計?當然,在我真正的問題中,我很少有父母Car和幾個孩子,所以我在一棵樹的中間。

+0

'因此看起來很自然的做一個繼承'看起來像你很快跳到這個結論:/特別是因爲你繼續使用半繼承,然後假裝繼承! –

+0

'DoubleCar'應該和'Car'有相同的功能,這就是爲什麼我會得出這個結論。 – Dejan

+0

@petar爲了您的代碼使用['std :: shared_ptr's](http://en.cppreference.com/w/cpp/memory/shared_ptr)而不是自己處理原始指針 – Mgetz

回答

1

在我看來,一輛「雙車」就像一輛卡車一樣,就像「汽車」一樣,而你試圖強行注入繼承關係的做法只是搞亂了你的概念模型。

例如,你的「雙人車」不是包含兩輛車。它包含的引擎數量是普通汽車的兩倍,是普通汽車的兩倍,但不包含兩輛汽車。

我會失去對Car完全的關係,只是專注於創作這些可重用的組件類型(如Engine):

/** Has "car" in the name, but isn't a car. Cars are single-engined. */ 
class DoubleCar 
{ 
    Engine e1, e2; 

public: 
    virtual void Start() { e1.Start(); e2.Start(); } 
}; 

如果你絕望的共享接口,我會去沒有比「車輛」級別更進一步,提供了一個純粹的虛擬Start和其他任何你有。

0

一個DoubleCar應該繼承汽車的公共接口數據兩路車。即你需要更清晰的數據和行爲分離。用Start,Stop,Accelerate, TurnLeft等方法定義汽車的抽象界面。繼承您的SingleCarDoubleCar。並且用車輪,發動機等組成一個汽車組件的數據實體。在你的DoubleCar裏面彙總它的兩個副本。

1

通常繼承模型「是一種」關係。通常這是從通用基類到更具體的派生類。例如:一輛汽車是一輛車。福特野馬是一輛汽車。因此,建模您可能會得到一個基類Vehicle,然後是Car的派生類,然後是FordMustang的派生類。

現在,如果我們試圖說「雙車是一輛車」,那聽起來有點奇怪。這不只是一輛車。這是兩個。

如果我們要說「雙車是由兩輛車組成」,那聽起來很合理。所以最終可能會有一個DoubleCar類擁有兩個Car成員。這更接近你最後的想法,但不會從Car中派生出來。

在這一點上,如果我寫代碼,我會開始質疑我的設計。 DoubleCar是否有任何理由繼承Car? 「擁有相同的成員職能」還不夠。你會不會需要通過一個需要汽車參考或指針的界面來提供DoubleCar?如果不是,那麼也許它不應該從汽車派生出來。在這種情況下,組合構思起作用,DoubleCar本質上是一種Car容器。

但是,如果不瞭解更多關於實際情況的具體情況,我不確定我可以給出更好的建議。