2011-06-17 84 views
6

我有一個數據類型,例如class Vector3。現在我需要創建幾個與Vector3具有相同接口但具有更高級別語義的類(例如:Position,Velocity)。使用typedef是不夠的,因爲我需要這些類型是不同的,以便它們可以用於重載。在C++ 0x我大概可以使用構造函數繼承:C++語義類型包裝

struct Position: public Vector3 { 
    using Vector3::Vector3; 
}; 

可以有任何問題呢?有沒有更好的方法來做到這一點?是否可以在不使用C++ 0x特性的情況下完成,而不必明確寫出所有Vector3構造函數?

+0

這樣做的問題是,位置是隱式轉換爲向量(這從技術上來說,矢量現在必須有一個虛析構函數,以便安全地使用) – jalf 2011-06-17 08:20:12

+0

@jalf :即使派生類沒有添加任何數據或方法,虛擬析構函數是否真的需要? – 2011-06-17 08:26:14

+0

jalf:我在我的回答中討論轉換主題 – sehe 2011-06-17 08:27:27

回答

5

考慮使用標籤結構

struct tagPosition {}; 
struct tagDirection {}; 
struct tagGeneric {}; 

namespace detail 
{ 
    template <typename Tag=tagGeneric> 
     class Vector3 
    { 
     // business as usual 
    }; 
} 

typedef detail::Vector3<tagPosition> Position; 
typedef detail::Vector3<tagDirection> Direction; 
typedef detail::Vector3<tagGeneric> Vector3; 

加分,有轉換操作符/構造:

template <typename Tag=tagGeneric> 
     class Vector3 
    { 
     template <typename OtherTag> 
      explicit Vector3(const Vector3<OtherTag>& rhs) { /* ... */ } 

//  template <typename OtherTag> 
//   operator Vector3<OtherTag>() const { return /* ... */ } 
    }; 

如果你喜歡驚險的生活,你可以刪除explicit關鍵字,或啓用隱式轉換運算符。這將有中能夠使混雜像這樣操作員的決議「好處」:

Position pos; 
Direction dir; 
Generic gen; 

dir = gen + pos; // you see why I call it 'promiscuous'? 

我建議(代替)來定義這樣的情況下,明確運營商(無功能:)

Position operator+(const Position& v, const Translation& d) { /* .... */ } 

這樣,你的類模型反映了你的類的語義。

C++0x would possibly contain things to enable explicit conversion operators,IIRC:

在轉換構造的情況下,您可以通過聲明爲顯式的N1592 proposal綿延此關鍵字的語義所有轉換運營商構造器來關閉隱式轉換。聲明爲明確的轉換運算符不會執行隱式轉換。相反,程序員必須顯式調用

+0

如果你想在數學上是正確的,你應該只允許以下內容:Position + Vector = Position;位置 - 位置=矢量;方向==矢量;方向*速度=速度(速度以單位1 /時間爲單位_scalar_!)。位置不是嚴格的矢量,而是指向仿射空間的點。你的「速度*方向」令人困惑 - 這兩個都是向量,他們的產品意味着什麼? – 2011-06-17 08:33:29

+0

@Kerrek:我沒有這樣的假設,他們沒有關係。我的例子中的語義不需要是正確的,也不是不正確的。 _(另外,你怎麼能先說我的例子是錯誤的,然後才問我這是什麼意思?也許方向是一個Unity向量,注意樣本沒有指定方向可能**如何派生**來自Vector3。試想一下,爲了example_,它有適當的不變量)。 - 只是說! – sehe 2011-06-17 08:38:09

+0

@sehe:你讓'Velocity'成爲一個向量。現在速度時間方向可能意味着什麼?只是好奇! – 2011-06-17 08:39:42

4

當我需要的不同,但相似的類型,我通常使用一個虛擬模板參數,如(即興,通過編譯器的髒手不變)

template< class UniqueId > 
struct Blah {}; 

typedef Blah< struct AlphaId > Alpha; 
typedef Blah< struct BetaId > Beta; 

這可能是也可能不是你需要什麼。

乾杯&心連心,