2012-07-09 108 views
0

這就是我的意思是鑄造POD對象,使用的static_cast

class V3 
{ 
public: 
float x,y,z; 
}; 

class V3_ 
{ 
public: 
float x,y,z; 
}; 

V3_ vec1; 
V3 vec2 = static_cast<V3_>(vec1); 

我應該怎麼做,使在編譯時該模具的工作?

謝謝。

編輯:

似乎有什麼我想要做一些誤解。 我可以寫一個操作符到轉換,但我希望它在編譯時完成。

這裏是兩個允許static_cast的Vector3實現。我不知道它是如何工作的,但它確實有效。

http://www.ogre3d.org/docs/api/html/OgreVector3_8h_source.html

http://harry-3d-engine.googlecode.com/svn/trunk/NxOgreVec3.h

我能做到這一點投

void DynamicBody::SetLinearMomentum(const Vector3& vel) 
{ 
body->setLinearMomentum(static_cast<NxOgre::Vec3>(vel)); 
} 

我想我如何能做到這一點的解釋。

編輯:

經進一步調查,我發現它實際上是如何做到這一點, 它調用

template<class user_xyz_vector_type> 
inline user_xyz_vector_type as() const { ... } 

不是一個實際的static_cast,但編譯器接受它作爲一個。 我真的很希望將pod轉換爲彼此是一件實際的事情。

回答

4

此演員陣容在任何時候都無法使用。你不能完全不相關,也不能相互轉換類型。

我不知道你正在嘗試做的,所以我不知道是什麼工作的「工作」,在這種情況下意味着,但在原始內存級別的轉換可以通過reinterpret_cast

V3 vec2 = reinterpret_cast<V3_&>(vec1); 
進行

但這是一個醜陋的黑客,不能保證工作,因爲,再次,你的類型是無關的。有了同樣的程度(甚至更好)的成功,你可以簡單地將一個對象memcpy變成另一個對象。

+3

'memcpy'更好,甚至。如果'V3'和'V3_'具有相同的佈局,並且通常對於給定的編譯器來說是相同的,那麼它就可以保證工作,沒有理由將它們放在不同的位置。使用'reinterpret_cast',你可以控制優化器是否利用嚴格的別名規則:你可以很容易地得到在-O1下工作的代碼,並在'-O3'上失敗,這取決於vec1何時何地'被初始化。然後reinterpret_cast – 2012-07-09 18:58:42

+0

。 – mikbal 2012-07-09 19:32:14

+0

@mikbal:'reinterpret_cast'可能很容易因爲Steve Jessop的評論中描述的原因而失敗。 – AnT 2012-07-09 19:54:51

0
V3_ vec1; 
V3 vec2 = *(V3*)&vec1; 

編輯:仍然,你知道這可能不是一件好事嗎?

1

你可以儘量避免使用完全鑄成:

V3 vec2 = {vec1.x, vec1.y, vec1.z}; 

或寫轉換功能:

V3 to_V3(V3_ const & v) 
{ 
    V3 v3 = {v.x, v.y, v.z}; 
    return v3; 
} 

,並用它作爲:

V3 vec2 = to_V3(vec1); 
+0

理想(我在這裏挑剔)會繼續正常工作,或者在第四個數據成員添加到這兩個類時停止編譯。你的'to_V3'函數可以有一個或多個靜態斷言,足以確保'V3'沒有任何額外的數據成員不明。 – 2012-07-10 09:57:38

+0

@SteveJessop:靜態斷言這兩個類的大小,還是其他的東西? – Nawaz 2012-07-10 10:04:37

+0

我在想,班級大小是相同的,(對於這個例子),你複製的字段大小的總和等於班級大小。如果一個類中有填充,並且有人添加了一個適合填充內容的新數據成員,那麼您將永遠不會通過查看大小來檢測它。所以我的建議在所有情況下都不是完美的,但它不應該對由多個浮體組成的結構產生任何誤報。 – 2012-07-10 10:25:30

1

的類型是不相關的,因此,你需要reinterpret_cast

V3_ vec1; 
V3 vec2 = reinterpret_cast<V3_&>(vec1); 
0

static_castV3V3_使用public:V3類的聲明。 class V3 : public V3_。這樣你可以轉換對象。如果你想要多態性,並且你意識到你在做什麼,就使用虛擬解構器。

+1

如果您要更改'V3'的定義,那麼您可能只需'typedef V3_ V3;';-) – 2012-07-09 19:00:12

+0

如果V3_的功能和類型與V3不同,則不適用。這很可能是一個子類的類型轉換,如'class A:public B'' class B'' void B :: function(){A * p =((A *)this); }而不是對象typedef – 2012-07-09 19:14:18