2014-06-08 31 views
0

由於我是面向對象編程的初學者,我很抱歉。如果只知道基類,那麼如何傳遞派生類?

我有一個名爲Hero的基類,有三個派生類Archer,Warrior和Mage。提示用戶選擇其中之一,並創建適當的派生類的對象。它們具有不同的初始值和成員函數,下一步是將此對象傳遞給另一個函數。

假設這個函數叫做battle(),它把對象作爲參數。我如何去做這件事?我是否必須創建三個單獨的戰鬥()或者是否有一種方法可以在不需要指定派生類的情況下傳遞對象?

void Hero::init(string job) 
{ 
    if (job == "archer") 
     Archer archer; 
    else if (job == "mage") 
     Mage mage; 
    else 
     Warrior warrior; 

    battle(); // What to put as argument? 
} 

回答

3

battle()應將引用或(智能)指針指向基類作爲參數。例如:

void battle(std::shared_ptr<Hero> ptr); 

而且你的說法應該是一個智能指針,以及:

void Hero::init(const std::string& job) 
{ 
    std::shared_ptr<Hero> ptr; 

    if (job == "archer") 
     ptr = std::make_shared<Archer>(); 
    else if (job == "mage") 
     ptr = std::make_shared<Mage>(); 
    else 
     ptr = std::make_shared<Warrior>(); 

    battle(ptr); 
} 

std::shared_ptr是智能指針類,它封裝了動態內存分配和資源獲取的指針。這樣我們就不必在每個地方寫new。此外,當智能指針被銷燬時(意味着不存在更多的ptr副本,如果有的話),則在所包含的Hero指針上調用delete

上述工作是因爲所有三個類都是從Hero派生的,因此這些派生類指針的地址可以由基類指向。

+0

std :: shared_ptr和std :: make_shared似乎沒有編譯。我正在使用最新版本的代碼塊。 – geft

+1

@geft您需要'#include'''文件。 – 0x499602D2

3

不,你不必創建3個不同的battle功能,避免這恰恰是繼承的目的。

您可以創建一個battle功能:

void battle(Hero& hero) 
{ 
} 

你可以稱它爲如下:

battle(archer); 
battle(mage); 
battle(warrior); 

但您將需要以另一種方式來創建你的英雄,因爲他們正在創建現在,只要ifelse完成,它們就會超出範圍。

+0

謝謝,但是'Hero&'是什麼意思?我不熟悉這個概念。 – geft

+1

這是一個參考。這意味着你使用在戰鬥函數外創建的對象 – alain

2

這是你應該使用運行時多態性的地方。
而不是創建本地派生類對象實例,創建一個基類指針,它指向派生類的實例:

Hero* hero = new Archer(); 
Hero* hero = new Mage(); 
Hero* hero = new Warrior(); 

然後,你可以基類指針Hero*傳遞給你的方法battle

battle(hero) 

您方法的簽名爲:

void battle(Hero*) 

This m Eans,戰鬥方法可以在運行時接受任何種類的英雄,無論是射手,法師還是戰士。

+1

這仍然會創建派生類對象實例。 –

+0

重述了這句話。 – cppcoder

+0

@cppcoder我有點困惑。你聲明一個指針,而不是指向一個動態分配的對象。當指針和對象是不同的類時,這是如何工作的? – geft

相關問題