2010-06-08 15 views
10

我目前正在研究需要在3D引擎,物理引擎和腳本語言之間移動數值的遊戲「引擎」。由於我需要將物理引擎中的矢量應用於3D對象,並希望能夠通過腳本系統控制3D以及物理對象,所以我需要一種機制來轉換一種類型的矢量(例如(例如btVector3)。不幸的是,我不能假定類/結構是如何佈局的,所以簡單的reinterpret_cast可能不會。非會員轉換功能;投射不同的類型,例如DirectX矢量到OpenGL矢量

所以,問題是:是否有某種「靜態」 /非會員的鑄造方法來實現基本上是這樣:現在這不會編譯因爲鑄造運營商需要爲成員方法

vector3d<float> operator vector3d<float>(btVector3 vector) { 
    // convert and return 
} 

btVector3 operator btVector3(vector3d<float> vector) { 
    // convert and return 
} 

。 (error C2801: 'operator foo' must be a non-static member

回答

5

我建議寫他們作爲一對自由函數(即不用擔心使他們「運營商」):

vector3d<float> vector3dFromBt(const btVector3& src) { 
    // convert and return 
} 

btVector3 btVectorFrom3d(const vector3d<float>& src) { 
    // convert and return 
} 

void f(void) 
{ 
    vector3d<float> one; 
// ...populate... 
    btVector3 two(btVectorFrom3d(one));  
// ... 
    vector3d<float> three(vector3dFromBt(two)); 
} 
+0

感謝亞當!這就是我現在所做的。我想知道是否有可能讓編譯器完成這項工作。就像「如果你想去那裏,先去那裏」。 – sunside 2010-06-08 19:10:12

+0

我明白。雖然這個解決方案似乎對我來說最直接,但我在另一個答案中增加了另一種可能 – 2010-06-08 21:35:39

+0

使用免費功能。隱式轉換通常是一個糟糕的途徑,即使它們是可以接受的。 – jalf 2010-06-08 22:47:03

1

您的問題聲明是正確的。類型轉換運算符需要是非靜態成員。如果你真的想轉換型語義,可以延長每一個這些類使用的應用程序中的代碼:

// header: 
class ConvertibleVector3d; 

ConvertibleBtVector : public btVector3 
{ 
    operator ConvertibleVector3d() const; 
} 

ConvertibleVector3d : public vector3d<float> 
{ 
    operator ConvertibleBtVector() const; 
} 

//impl: 
ConvertibleBtVector::operator ConvertibleVector3d() const 
    { 
    ConvertibleVector3d retVal; 
// convert this into retVal... 
    return retVal; 
    } 

ConvertibleVector3d::operator ConvertibleBtVector() const; 
    { 
    ConvertibleBtVector retVal; 
// convert this into retVal... 
    return retVal; 
    } 

void f(void) 
{ 
    ConvertibleVector3d one; 
// ...populate... 
    ConvertibleBtVector two(one);  
// ... 
    ConvertibleVector3d three; 
    three = two; 
} 

的名字是一個有點冗長,但希望的意圖十分明顯。

公共繼承意味着您應該能夠以與基類相同的方式使用這些類的實例,除非它們可以相互分配和構造。當然,這會結合兩個類,但這可能是可以接受的,因爲它聽起來就像你的應用程序打算做的那樣。

+0

謝謝!我接受了另一個答案。這個感覺更自然,但是因爲並不總是可以修改庫代碼(儘管在這種情況下是這樣)......等等。 :) – sunside 2010-07-19 13:43:29

2

你也可以使用一個模板包裝類,如:

template<class V> 
class vector_cast {}; 

template<> 
class vector_cast<vector3d> { 
    const vector3d& v; 

public: 

    vector_cast(const vector3d& v) : v(v) {}; 

    operator vector3d() const { 
    return vector3d(v); 
    } 

    operator btVector3() const { 
    // convert and return 
    } 
}; 

template<> 
class vector_cast<btVector3> { 
    const btVector3& v; 

public: 

    vector_cast(const btVector3& v) : v(v) {}; 

    operator btVector3() const { 
    return btVector3(v); 
    } 

    operator vector3d() const { 
    // convert and return 
    } 
}; 

用法:

void set_origin(btVector3 v); 

// in your code: 

vector3d v; 
// do some fancy computations 
set_origin(vector_cast(v)); 

// --- OR the other way round --- // 

void set_velocity(vector3d v); 

// in your code: 

btVector3 v; 
// do some other computations 
set_velocity(vector_cast(v));