2011-07-31 16 views
0

我努力讓自己在C++某種奇怪的多態性:發出奇怪的多態性

我的班兩棵樹:

國家< - 舞臺< - Stage_1,Stage_2,Stage_3

行動< - ActionState < - ActionState_Clear,ActionState_Begin,ActionState _ [...]

我想定義上Stage_1一些方法得到一個動作作爲參數:

State 
{ 
    virtual void exec_action(Action *tAct) 
    { 
     std:cout << "NOT IMPLEMENTED" << endl; 
    }; 
} 

Stage_1 
{ 
    virtual void exec_action(ActionStage_Clear *tAct) 
    { 
     std::cout << "ACTION STAGE CLEAR" << endl; 
    } 

    virtual void exec_action(ActionStage_Begin *tAct) 
    { 
     std::cout << "ACTION STAGE BEGIN" << endl; 
    } 
} 

Action *pAct = new ActionStage_Clear(); 
State* pSta = new Stage_1(); 

**pSta->exec_action(pAct);** 

我想讓它顯示'ACTION STAGE CLEAR',但它顯示'NOT IMPLEMENTED'。這是 - 我認爲 - 因爲沒有任何exec_action(Action *)的實現(儘管它的子類有一些)。

編輯:我會告訴你一下圖的一小部分: 我有舞臺和動作(s)。我將有一個ptr到Stage_1,2 ..和一個ptr到Action_1,2 ... 我想要調用Stage_n-> exec_action(Action_n)並且應該執行子的代碼:Action_1 :: exec_action (ACTION_1)。 (如果它沒有實現,它應該調用Action :: exec_action(Action))。

Design 問題是

我怎樣才能解決這個問題? 有沒有其他方法可以使它工作?

謝謝,原諒我的英文。

+0

這顯然不是你真正的代碼;請發佈您的實際代碼。 –

+0

這是你真正的C++代碼嗎?我沒有得到你定義類的地方。另外,你在哪裏繼承? –

+0

不是真正的代碼(顯然!),我現在發佈它 – josec89

回答

1

您可以在基類只覆蓋contravariantly:在派生類方法的參數的類型必須爲少衍生比一個基類。

否則(就像你的情況),你只是在寫一個不同的函數。

+0

我明白了......所以想法如何使它工作?我編輯帖子,以表明我的意圖 – josec89

+0

@josec:你真的想在這裏雙重派遣。如果1)繼承層次較小,訪問者模式儘管實施起來很麻煩,但可能是解決方案2)您期望動作的數量增長。 –

+0

我期望動作的數量增長很多(有3種動作 - > ActionObject,ActionStage,ActionPhase - > ActionObject_Create,ActionObject_MoveLeft ....並且有3種狀態 - > ObjState,Stage,階段 - > ObjState_Idle,ObjState_Jumping .....我已經通過實現Visitor模式解決了這個問題,但是我已經在'父類'狀態聲明瞭所有的虛擬exec_actions狀態 – josec89

2

你想double dispatch在這裏。虛擬功能直接只提供一個。雙派遣的一個很好的例子是Visitor pattern,它可以直接適用於你的任務。

+0

所以,我只需要實現Visitor模式,這在C++中是可能的,是不是? – josec89

+0

@josec,你必須實施雙重派遣,訪客是一個例子。這取決於你設計的細節。和C++一樣,這是絕對有可能的。 – unkulunkulu

+0

我已經看過訪客模式,但我有一個問題。如果我要實施該解決方案,我是否必須在州內包含所有「未實施」方法? :class State {virtual exec_action(ActionStage _ [....] * tAct); ....} – josec89