2011-03-24 50 views
1

我有一個用於3D矢量數學的模板矢量類。我想有這個類不同類型和尺寸的變體(如Vec2i,Vec2f,Vec3i,Vec3f),並能夠構建一個從其他,像這樣:模板的代碼重用問題3D數學的矢量類

Vec2i v(1, 2); 
Vec3f u = Vec3f(v, 0); 

目前,我有一個Vector中用於完成此操作的構造函數的數量。然而,這似乎不正確,允許在與上述相同的方式來構建一個Vec4:

Vec4f t = Vec3f(v, 0) 

我想有單獨的類VEC 2 *,* VEC3,Vec4 *變種,但是這意味着代碼的重複。我應該怎麼做?從基類Vector類繼承?按照原始的Vector類實現每個變體(即Vector類是每個變體的私有成員)?

回答

1

一個VEC 2和VEC3有很大的不同IMO,你所期望的代碼重用,如果他們有關係嗎?

對於不同的內置類型,簡單地使用模板類和模板的構造函數:

template<typename T1> 
struct Vec2 { 
    Vec2(T1 const & X, T1 const & Y) : x(X), y(Y) {} 
    template <typename T2> 
    Vec2(Vec2<T2> const & V) { 
     x = static_cast<T1>(V.x); 
     y = static_cast<T1>(V.y); 
    } 

    T1 x, y; 
}; 


template<typename T1> 
struct Vec3 { 
    Vec3(T1 const & X, T1 const & Y, T1 const & Z) : x(X), y(Y), z(Z) {} 
    template <typename T2> 
    Vec3(Vec3<T2> const & V) { 
     x = static_cast<T1>(V.x); 
     y = static_cast<T1>(V.y); 
     z = static_cast<T1>(V.z); 
    } 
    template <typename T2, typename T3> 
    Vec3(Vec2<T2> const & V, T3 const & Z) { 
     x = static_cast<T1>(V.x); 
     y = static_cast<T1>(V.y); 
     z = static_cast<T1>(Z); 
    } 

    T1 x, y, z; 
}; 

如果你想VEC 2和VEC3相關,有VEC 3模板繼承VEC 2模板,然後隱藏功能你需要重寫Vec3。

+0

我最終做了類似的事情;我創建了一個Vec2,Vec3,Vec4,Point2和Point3實現的基類Vector類,以便重用Vector的功能,但僅暴露其操作的子集(如Point2和Point3的情況)或添加功能(專門的構造函數)。 – 2011-06-03 18:46:22

1

使用模板。這完全沒有經過測試。

template <int N> 
struct Vec 
{ 
    Vec(const Vec<N - 1>& smaller_vec, double v) { std::copy(&smaller_vec.values[0], &smaller_vec.values[0] + N-1, &values[0]); values[N-1] = v; } 

    double values[N]; 
}; 

template <> 
struct Vec<1> 
{ 
    Vec(double v) { values[0] = v; } 

    double values[1]; 
}; 

Vec<3> v3(Vec<2>(Vec<1>(5), 6), 7); 
1

是這樣的嗎?

template <int size, typename T> 
struct Vec 
{ 
    Vec<size, T>() {} 
    Vec<size, T>(Vec<size-1, T>, T val) {} // here's the fun 
}; 

typedef Vec<2, float> Vec2f; 
typedef Vec<3, float> Vec3f; 
typedef Vec<4, float> Vec4f; 
// ... 

int main() 
{ 
    Vec2f john; 
    Vec3f casey(john, 0); 
    Vec4f chuck(casey, 0); 

    return 0; 
}