2010-07-12 179 views
5

我有兩個班,點和像素:C++繼承/模板問題

class point { 
    public: 
     point(int x, int y) : x(x), y(y) { }; 
    private: 
     int x, y; 
} 

template <class T> 
class pixel : public point { 
    public: 
     pixel(int x, int y, T val) : point(x, y), val(val) { }; 
    private: 
     T val; 
} 

現在,這裏是我的問題。我想創建一個容器類(我們稱之爲coll),它具有點或像素的私有向量。如果一個coll的實例包含像素,我希望它有一個方法toArray(),它將像素矢量轉換爲表示矢量內容的T數組。

我打算用繼承來做到這一點:也就是說,我可以製作一個包含點向量和包含額外方法的派生類的基類coll,但後來我似乎遇到了問題,因爲像素是一個類模板。

有沒有人有建議?我可以通過製作一個類模板來做到這一點嗎?

+0

我認爲'coll'也應該是一個模板類。然後,您可以部分專門化「coll」來獲取點和像素。 – Philipp 2010-07-12 15:45:27

+0

像素是一組座標(即繼承'點')還是它有座標(即包含一個點的實例)? – Patrick 2010-07-12 15:52:21

+0

它從點繼承。 – amc 2010-07-12 15:57:54

回答

3

問題:你的意思是私人載體同時包含點和像素,還是隻包含一個或另一個?

問題:如果只是一個或另一個,你是否意味着在相同的專用矢量中混合具有不同模板參數的像素?

假設它僅僅是點或像素私人向量,使得像素私人矢量都具有相同的模板參數,你可以做這樣的事情:

template < class T > class CollectionBase 
{ 
    //common interface here 
    protected: 
    std::vector<T> coll_vec; 
}; 

class PointCollection : public CollectionBase<Point> 
{ 
    public: 
    ... 
}; 

template< class T> PixelCollection : public CollectionBase<Pixel<T> > 
{ 
    public: 
    Pixel<T>* toArray(); 

    ... 

}; 
+0

答:只是一個或另一個。 答:只是具有相同模板參數的像素。 這個解決方案看起來不錯,但我的集合將具有很多相同的功能:這不需要大量重複相同的代碼,因爲CollectionBase將無法訪問容器? – amc 2010-07-12 16:05:33

+0

@amc更新了防止代碼重複的答案。它有點讓PointCollection有點多餘,但是這會阻止大部分從PixelCollection轉換爲PointCollection,反之亦然。如果你打算讓它們在對方之間轉換,那麼你可以將CollectionBase和PointCollection合併爲一個類。 – diverscuba23 2010-07-12 16:39:39

+0

真棒,這正是我想要的。我想我沒有意識到你可以繼承一個模板類。謝謝! – amc 2010-07-12 16:52:38

1

如果你想檢查一個point對象是否也是pixel<T>類型,那麼您可以簡單地看看dynamic_cast是否返回NULL。爲了做到這一點,point將需要多態,所以添加一個虛擬析構函數。

下面是一個例子:

point x(0, 0); 
pixel<int> y(0, 0, 0); 
point *pX = &x; 
point *pY = &y; 
if(dynamic_cast<pixel<int> *> (pX) != NULL) { 
    std::cout << "x is a pixel<int>."; 
} 
if(dynamic_cast<pixel<int> *> (pY) != NULL) { 
    std::cout << "y is a pixel<int>."; 
} 

輸出如下:

y是像素< int>的。

您可以在您的coll類中使用此代碼來檢查vector<point *>的每個元素是點還是像素。但是,爲了做到這一點,你需要知道的是存儲該像素的專業化(即它是一個pixel<int>pixel<float>?)

這可能是簡單的方式,coll類模板。

1

如果collection對待point s和pixel s大多是相同的,只包含一個或另一個,它是有意義的,使它成爲一個模板類。
關於to_array但是,它可能是簡單的做它,而不是一個自由的功能:

template<class T> struct collection { 
    std::vector<point<T> > data_; 
    // ... 
}; 

template<class T> 
void to_array(const collection<point<T> >& in, point<T>* out) { 
    // ... 
} 

注意,你將不得不但是提供讀取訪問數據的公共接口或至少選擇地授予to_array()訪問。