2012-07-25 129 views
0

我對box2d很新穎,我試圖使用b2body對象中的userdata(類型爲void *)字段來存儲int值(枚舉值,所以我知道對象的類型)。C++和box2d:userdata將int轉換爲void *

我現在正在做的事情是:

int number = 1023; 

void* data = (void*)(&number); 

int rNumber = *(int*)data; 

,我得到正確的價值,但我一直在讀圍繞鑄造到void *它不是便攜或推薦...是我的代碼跨平臺?它是行爲定義還是實施依賴?

謝謝!

+1

Windows API會一直這樣做(甚至更糟糕)。如果沒有其他方式存儲它以備後用,沒有多少選擇,但是是一個空指針。你可以用適當的C++類型轉換來完成,但是(第一個不投射,第二個投射爲「static_cast」)。 – chris 2012-07-25 07:44:23

回答

2

實際上,您不投intvoid*,你投int*void*,這是完全不同的。

指向任何類型的指針都可以存儲在void*中,並且可以再次轉換回相同的類型。這是保證工作。

由於語言標準沒有說不同的指針必須具有相同的大小,或者以相同的方式工作,所以轉換爲任何其他類型都不是可移植的。只要void*必須足夠寬以包含它們。

4

鑄造到void *是便攜式。不建議使用,因爲您正在失去型號安全。任何東西都可以放入void *,任何事情都可以得到。它可以讓你更容易地在腳下拍攝自己。否則void *是好的,只要你小心謹慎和謹慎。

1

void*的其中一個問題是,您需要知道(記錄)它原來的類型才能正確投射。如果它最初是一個float,而你將其編譯爲一個int,編譯器只會說出你的話。

爲了避免這種情況,您可以爲包含該類型的數據創建包裝,這樣您就可以始終將其轉換爲正確的類型。

編輯:你也應該用C++鑄造風格而不是C即reinterpret_cast

+0

那些有什麼區別? – 2012-07-25 07:57:25

1

無效*的習慣是某種過去(ISO C)的遺物,但非常方便。只要你小心地迴轉並轉發你想要的類型,就可以安全地使用它。考慮像C++類系統或重載函數

反正你將有更好的轉換操作符其他替代品,有時周圍有沒有其他的方法(void *的),另外一些時候,他們只是太方便了。

它可能會導致不可移植的代碼,而不是因爲鑄造系統,而是因爲一些人試圖與他們進行非便攜式操作。最大的問題在於(void *)與內存地址一樣大,在很多平臺中恰好也是平臺整型的長度。

然而,在某些罕見的例外大小(無效*)!=大小(INT)

如果你試着做一些類型的操作/魔法與他們沒有鑄造回到你想要的類型,你可能有問題。你可能會驚訝的我多少次看到有人想要一個整數存儲到一個void *指針

+0

他在Box2D中提到的void指針是爲了方便使用框架的人。它允許您將Box2D世界中的對象返回到您引擎中您自己的對象之一。沒有任何其他實際的方法來做到這一點沒有void *。 – 2012-10-21 03:47:05

1

要回答你的問題,是的,這是安全的。

要回答你沒有問過的問題,void指針不是用來保存int的。Box2D有指針指向你的遊戲引擎中的實體對象,所以你可以關聯一個物理模擬中的實體在你的遊戲中的b2Body。當一個b2Body與另一個b2Body交互時,它可以讓你更容易地編程實體與另一個實體進行交互。

所以你不應該只是把枚舉放在那個void *中。您應該直接將其指向由該b2body表示的遊戲對象,該對象可能具有枚舉。

+0

我不認爲這是公平的說userData是'for'以外的東西,而不是保存一些開發人員想要保留在那裏的信息。 – Maxxx 2014-03-13 11:01:02