2011-08-20 44 views
-1

來自PHP背景,我試圖學習C++,因爲我覺得它是一種有趣的語言。作爲一種習慣,我想用模板創建一個簡單的Vector類,這不是很難。但是,我遇到了一個問題。在我的基本向量類中使用數組作爲模板參數

我已經創建了下面的模板類:

template <typename T> 
class Vector 
{ 
public: 
    Vector(int length); 
    ~Vector(void); 
    int getLength(); 

    T& operator[] (const int index); 

private: 
    T *_items; 
    int _count; 
}; 


template <typename T> 
Vector<T>::Vector(int length) 
{ 
    _items = new T[length]; 
    _count = length; 
} 

template <typename T> 
T& Vector<T>::operator[](const int index) 
{ 
    if (index >= getLength() || index < 0) 
     throw exception("Array out of bounds."); 
    return _items[index]; 
} 

所有的功能都實現,但他們不相關的我的問題,所以我在這裏沒有複製它們。

該類按預期工作,但有一個例外: 如果我想創建一個數組的向量,它不起作用。 例如: -

Vector<int[2]> someVector(5); 

我明明想的是,Vector類的_items屬性將是int [5] [2]。但是,由於編譯器將'T'替換爲'int [2]',_items屬性將爲int [2] [5](或者至少,這是我從調試中瞭解到的,如果我錯了,請糾正我的錯誤)。結果,[]運算符不再正常工作,因此這個整個類對於數組沒有用處。

有沒有辦法解決這個問題,讓這個類也適用於數組?如果這是不可能的,有沒有辦法阻止這個類被數組初始化?

編輯:謝謝你迄今爲止的所有迴應。但是,我可能不完全清楚我的問題。首先,我創建了這個類來習慣C++,我知道有一個std :: vector類,而且現在我最好使用矢量向量。這不是真的問題。我只想更好地理解模板,並且通常使用C++,所以我想知道如何處理這類問題。我希望能夠創建不會導致程序崩潰的類。如果我或者其他人現在會使用這個類並且試圖使用原始數組而不是向量來創建這個類,那麼程序會因爲數組錯誤而崩潰(Vector(y)變成int [x] [y ]而不是內部的int [y] [x])。所以我想要一個解決方案,它可以創建正確的數組,或者防止矢量被數組初始化。

+4

確保你有[一本好的入門C++書](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。學會在不理解語言基礎的情況下編寫出色,正確,無錯的C++代碼是非常非常困難的。 –

+1

「使用不太難的模板」 - 如果您正在討論製作自己的模板類/函數,那麼「模板」和「不太難」不會真正適合同一句話。這很棘手。 – Mat

+0

要添加到Mat的評論:模板可以很難,特別是如果你想讓他們迎合非基本類型(如你的int [2]對象)。他們不是一個很好的學習C++的方法,並且這不是一個很好的例子,可以從優秀的STL Vector對象中學習。 – Pete855217

回答

7

很簡單,永遠不要使用內置的原始數組。爲了任何東西。他們非常吸引人。如果您沒有TR1或C++ 0x,則始終使用類包裝器(例如boost::array),這兩個類也都提供array類。一個Vector<boost::array<int, 2>>將平凡編譯。爲什麼不用原始數組?

它們對指針有可怕的隱式轉換,在帽子下面忘記它們的大小,不是一流的公民(例如不能分配給它們),例如不檢查它們的邊界。 boost::array<int, 2>完全是一個沒有蹩腳轉換的原始數組,完全是通用的 - 例如,您的Vector模板可以很好地與boost::array<int, 2>無關,並且可以在at()函數中進行邊界檢查。

我不是建議使用動態數組。 boost::array不是動態大小的數組。它是一個常量大小的值類型的數組,它不會轉換爲指針,它具有用於標準庫中的函數,如begin,end,size,它可以像其他任何類型一樣處理 - 不像數組,它有一個一打特殊規則 - 就像你發現的那樣。

+0

爲什麼我不應該使用原始數組?我認爲在很多情況下Vector類會過度殺傷,並且基本數組就足夠了,特別是在編譯時知道元素數的情況下。然而,由於我認爲你更有經驗,所以我錯了,比你錯了,所以你也可以解釋爲什麼我不應該使用它們? – Tiddo

+0

@Tiddo - 它不是「從不」,它是「幾乎沒有」。原因是「他們非常吸引人」。 C語言中的內置數組是一種可以一直困擾我們的黑客。他們忘記了他們的體型,他們在一絲風中腐化成指針,而且他們不使用容器。或用'new'。 –

+0

@Bo - 更糟糕的是,他們根本不知道它們的大小,與引用唯一的區別在於,您默認通過值來傳遞它們的權利?如果我錯了,請糾正我。 – Tiddo

0

條件必須說index >= getLength(),因爲的getLength()不是允許索引值太(第一個元素的索引是0,最後的是getLength()-1

+1

不錯,但你不應該把它當作答案,因爲它與問題無關。 –

+0

這很可能是他的問題的原因。 – hamstergene

+0

@Eugene:如果他的索引計算關閉,它如何用於整數但不是int數組。 – Puppy

5

我看到了一些東西錯。

  1. 如果你正在製作一個通用向量類,爲什麼要處理一個數組向量而不是矢量向量呢?

而不是限定int類型的向量[2],嘗試使大小爲2的向量的向量,其具有這樣的事情:

Vector<Vector<int>> vector(5); 
for (int i = 0; i < 5; i++) 
{ 
    vector[i] = Vector<int>(2); 
} 
  1. 而不是使用恆定大小的數組,嘗試使用指針。

而不是使用指向大小爲2的數組的指針,請使用指向指針的指針併爲該指針分配兩個空格。指針在C++中處理起來要容易得多,因爲您只需傳遞指針的地址而不必複製整個數組。傳遞數組通常是非常糟糕的形式。

  1. 添加默認參數構造函數

而不是Vector(int length);聲明構造函數中,嘗試使用Vector(int length = 0);因此,如果用戶沒有指定的長度,則默認爲一個大小爲零。

最後,你是否知道事實上有一個std :: vector,或者你是否意識到這一點,並試圖複製它?已知模板是C++中最難的主題之一,祝你好運!

+0

恆定大小的數組比雙向Vector更快,更安全,應儘可能使用。 – Puppy

+0

儘管我在原始文章中沒有提及它,但我知道如何使用數組向量來解決此問題。但是,我正在創建這個類,因爲我想更好地理解C++,並且我只想知道如何處理模板中的數組。我意識到std :: vector類,但正如我之前所說的,我只是將這個類創建爲一個練習。我喜歡指針的想法,但是我總是知道我應該以這樣的方式創建類,即使以最糟糕的方式濫用類時,應用程序也不應該崩潰。所以我確實希望能夠禁止這個模板的數組。那可能嗎? – Tiddo

+0

你不能禁止某些類型。你有沒有嘗試過使用std :: vectors類型並查看發生了什麼? –

相關問題