2013-05-15 36 views
1

調用非虛函數在派生類中作爲this answer指出:使用基類指針

上dynamic_cast的高度依賴往往是指示你的設計出了問題。

我想知道的是我怎麼能調用自定義函數在派生類中,針對其存在的基類中沒有同名的功能,但這樣做使用基類指針,也許如果實際上沒有dynamic_cast有更好的方法。

如果這個函數是一個在兩個函數中定義的虛函數,那很簡單。但是這只是派生類中的一個獨特功能。

也許dynamic_cast是最好的方式?

+7

嗯,這是事實,你想做你想做的事情,這是你的設計可以做一個返工的標誌。如果您需要*,請使用'dynamic_cast'。 –

+3

也許這只是我,但我懷疑你的設計有點不對。 – jrok

+0

出於興趣,什麼樣的情景會要求你這樣做? –

回答

5

爲了調用Derived類的函數,您必須獲取指向派生類的指針。作爲(視情況)的選項,您可能希望使用static_cast,而不是dynamic,但正如你所說的:

it is often an indication your design has gone wrong

此外,有時我覺得使用蒙上它的確定。當我爲遊戲設計GUI庫時,它有一個基類Widget和許多子類。一個實際的窗口布局是在一個編輯器中完成的,稍後一些Loader類正在膨脹這種佈局。爲了從佈局中填充小部件以及每個小部件數據的實際特定(遊戲相關),我製作了一個用於從小部件查詢小部件的子項的方法。此函數將其重新調整爲Widget*,然後將其dynamic_casted調整爲實際類型。我還沒有找到更好的設計。

後來我還發現Android是GUI系統的工作方式相同

+0

有趣,謝謝。我已經添加了一個新的問題,更詳細地介紹了我需要實現的內容。 http://stackoverflow.com/questions/16577697/struggling-with-design-decision-regarding-polymorphic-member – johnbakers

1

我想知道的是我怎麼能叫在派生類中...自定義函數沒有dynamic_cast如果事實有更好的辦法

正如引用中指出的那樣,這是一個設計問題,而不是實現問題。調用該函數沒有「更好的方法」; 「更好的方法」是重新設計你的類型,以便子類型不需要向父母添加功能。通過這樣做,你的類型可以滿足Liskov替換原則的一個共同解釋,並且更容易使用,因爲用戶根本不需要知道子類型。

如果以這種方式重新設計類型是不可能或不合理的,那麼也許您確實需要RTTI。建議並沒有說「所有用途......」,只是「高度依賴...」,這意味着RTTI應該是最後的手段,而不是默認的方法。

0

這更像是一個選項,然後是一個真正的答案,所以不要讓我陷入死亡。

class Derived; 

class Base 
{ 
public: 

    virtual Derived * getDerived()const 
    { 
     return NULL; 
    } 
}; 

class Derived : public Base 
{ 
public: 

    virtual Derived * getDerived()const 
    { 
     return this; 
    } 
}; 

我猜你得到的圖片...

附: Mike Seymour,感謝:-)

+0

這有何幫助? – dyp

+1

@DyP:從基類訪問少量潛在的派生類,如果沒有成熟的RTTI,可能是一種有用的攻擊手段;儘管你需要返回實際的子類型而不是'void *',因爲它甚至是非常安全的。不過,它的伸縮性並不好。 –

+0

@MikeSeymour您仍然必須將'void *'強制轉換爲'Derived *',所以我沒有看到這與'Base'的函數成員中的static_cast (this)'(或'reinterpret_cast')有什麼不同'。 – dyp