2016-07-21 55 views
1

我想這是一個經典,但在我的情況下,我有約束,應該簡化問題。C++:通過向下轉換擴展對象到派生類

這只是我得到了一些結構A在我的模塊的輸入,並且想要添加一些屬性。所以我創建了一個擴展A的結構B,並添加了我所需要的。

現在每當我調用一個期望B的方法但我給它一個A時,編譯器並不高興:一個對象可能不是Bs,就像所有的貓都不是獅子一樣。

但在我的情況下,我發誓,儘管使用較少的屬性,但所有的As都是Bs。沒有找到的屬性可以報告爲未初始化,這很好,我也發誓我在初始化之前永遠不會調用屬性。基本上,我在獲取A對象作爲輸入時首先要做的是填充剩餘的B屬性,這些屬性是基於A屬性計算的。我只是不想複製當我進入Bs只是爲了添加一些屬性,因爲然後As的屬性將被複制到內存中。我不會修改A的原始屬性,我只是要用它們來計算派生屬性,然後傳遞並使用A屬性和派生屬性處理B對象。

例子:

從常見的,項目級標題:

struct Rectangle { 
    // Side lengths 
    int a,b; 
} 

從局部標題:

struct LocalRectangle : Rectangle { 
    int area; 
} 

void updateModule(Rectangle inputRect); 

從本地源:

void updateModule(Rectangle inputRect) { 
    LocalRectangle r = (LocalRectangle)inputRect; 
    r.area = r.a*r.b; 
    // More processing ... 
} 

我如何做這個 ?

由於提前,

查爾斯

+0

你可以請郵編? –

+0

也許你可以添加一個字段到'std :: map'類型的As結構中,該結構將保存不同的屬性,並刪除Bs結構,成爲A類型的一切。 – LoPiTaL

+0

你可以修改'A'嗎? – Motti

回答

1

如果你可以修改A結構,你可以考慮只將這些值轉換爲A與未初始化值(使用指針或boost::optional)懶洋洋地初始化它們。

否則,如果您不能修改A和不希望的值從每個A複製到其相應B你可以考慮讓BA獲得,只是有附加屬性。然後,您將保持全球std::map<A*, B>[1],並通過在地圖中查找來查找其他屬性。如果您選擇此路徑,問問自己是否知道何時從map中刪除過時的A


  1. 我使用A*因爲要避免複製A秒。
1

如果A是一個具有少數屬性的B,那麼它不是B嗎?否則,我們可以從世界上的任何對象轉換到任何其他對象,只需查找具有相同名稱/特徵的屬性/方法即可。

但我不得不質疑你爲什麼要傳遞一個你知道不正確類型的對象。如果該方法不需要B提供的額外屬性,則改變它的簽名來取A *而不是B *。如果它確實需要這些值,那麼你不能傳入一個沒有它們的對象。

如果你確實真的必須這樣做,而且我認爲你看到我沒有看到這是一個好的設計,那麼也許考慮在需要一個A的地方製作一個靜態方法,然後返回一個新的B未知屬性設置爲null或其他。