2013-08-02 110 views
1

我試圖實現的數據結構來管理n維矢量,其中n將不大於50。如何在一種情況下實現具有顯着不同實現的類?

的問題是,n = 2的是具有相同的接口的特殊情況,但完全不同的實現。我怎樣才能實現這個?

我正考慮Ñ模板參數和:

  1. 使對於n = 2
  2. Copypaste一個模板偏特n的接口= 2
  3. 使用構建的數據結構工廠將有這種結構的原型實例化爲n = 2,3,...,50

有沒有更好的方法?如果我按照我的建議實施它,我應該注意什麼?

回答

3

答案取決於n在編譯時是已知還是隻在運行時才知道。

如果n在編譯時已知,那麼部分模板規範就是要走的路(本着與實現std::vector<bool>是模板規範相同的精神)。

如果n只知道在運行時,可以實現一個State Pattern保持內部的一個對象,以你的向量執行的操作,使得它的兩種實現方式,並隱藏矢量對象內部的指針,它的實例:

struct Vector; 

struct VectorOperations { 
    virtual void doOperation1(Vector& v) = 0; 
    virtual void doOperation2(Vector& v) = 0; 
}; 

struct VectorOperationsTwo: VectorOperations { 
    virtual void doOperation1(Vector& v); 
    virtual void doOperation2(Vector& v); 
} opsTwo; 

struct VectorOperationsThreeAndMore: VectorOperations { 
    virtual void doOperation1(Vector& v); 
    virtual void doOperation2(Vector& v); 
} opsThreeAndMore; 

class Vector { 
    VectorOperations *ops; 
public: 
    Vector(int size) { 
     ops = size == 2 ? (VectorOperations*)&opsTwo : &opsThreeAndMore; 
    } 
    void operation1() { 
     ops->doOperation1(); 
    } 
    void operation2() { 
     ops->doOperation2(); 
    } 
    friend class VectorOperationsTwo; 
    friend class VectorOperationsThreeAndMore; 
}; 

這個例子假設兩個元素的向量和兩個以上元素的向量將具有相同的數據成員,所以我做了opsTwoopsThreeAndMore共享。如果不是這種情況,您可以在構造函數內分配新的VectorOperationsTwoVectorOperationsThreeAndMore

+0

我實際上在這裏指的是*策略模式*,因爲一旦設置它不再改變。 *狀態模式*指的是一種隨着時間而演變的策略:它與一臺狀態機(從中繼承它的名字)密切相關。 –

+0

@MatthieuM。那麼,在這種情況下,它可能是一種策略或一種狀態,取決於API的其他部分。如果大小是在構造函數中設置的,並且再也不會改變,這是一種策略;如果我們讓創造者在創造後改變他們的規模,並相應地調整我們的戰略目標,它就會成爲一個國家。感謝編輯! – dasblinkenlight

3

IMO爲特殊情況n = 2提供一個實現的工廠,對於所有其他情況提供不同實現是最簡單和最優雅的實現方式。

+0

謝謝!現在我正在考慮什麼應該是工廠返回類型? –

+1

它取決於類的層次結構。如果n = 2的特殊情況作爲更一般類(n!= 2)的子類實現,那麼通用類是返回類型。如果n = 2和n!= 2都是一個(可能是抽象的)超類的子類,那麼這個超類就是返回類型。 –

1

我認爲容器尺寸在運行時是已知的,所以基於teplate專業化的解決方案不起作用。

那麼PIMPL成語呢?存儲兩個實現,一個用於一般情況,另一個用於特殊情況。

+1

N是這裏的尺寸,而不是尺寸。 – MSalters

1

模板偏特。接口的共享部分可以從非模板化(或至少非專業化)的基類繼承。

原因是數據的維度非常不是運行時變量,而是依賴於域。

相關問題