2010-06-02 104 views
2

我對如何在C++中使用矢量感到有些沮喪。我廣泛使用它們,雖然我不完全確定如何使用它們。以下是問題?C++矢量洞察

  1. 如果我有一個向量可以說:std::vector<CString> v_strMyVector,與(int)v_strMyVector.size > i我可以訪問我成員:v_strMyVector[i] == "xxxx";? (它的工作原理,但爲什麼?)

  2. 我是否總是需要定義一個迭代器來訪問矢量的開始,並在其成員上進行操作?

  3. 如果我直接訪問vector的所有成員(參見1),那麼迭代器的用途是什麼?

由於提前, 孫

+0

可能你的意思是 v_strMyVector [i] =「xxxx」; NOT v_strMyVector [i] ==「xxxx」; – Arseny 2010-06-02 14:43:38

+1

在#1中,你問爲什麼[]運算符工作,或其他? – 2010-06-02 14:46:30

+0

什麼奇怪的匈牙利 – Konrad 2010-06-02 15:01:20

回答

10
  1. 它的工作原理,只是因爲沒有邊界檢查爲operator[],出於性能的原因。這樣做會導致未定義的行爲。如果你使用更安全的v_strMyVector.at(i),它會拋出一個OutOfRange異常。

    這是因爲operator[]返回一個引用。

  2. 由於vector s可以在O(1)時間內隨機訪問,因此通過循環索引或迭代器不會產生性能差異。

  3. 迭代器允許您編寫獨立於容器的算法。這種迭代器模式在<algorithm>庫中被使用很多,以允許更容易地編寫通用代碼,例如,而不是需要N個元每個M個容器(即寫M * N個函數)

    std::vector<T>::find(x) 
    std::list<T>::find(x) 
    std::deque<T>::find(x) 
    ... 
    std::vector<T>::count(x) 
    std::list<T>::count(x) 
    std::deque<T>::count(x) 
    ... 
    

    ,我們只需要ň模板

    find(iter_begin, iter_end, x); 
    count(iter_begin, iter_end, x); 
    ... 
    

    和各部M容器提供的迭代器,減少了只需要M + N的功能數量。

+0

我贊成這個,因爲這或多或少是我會回答的,儘管我認爲你誤解了他的問題#1(公平地說,我認爲我不明白他的#1,因爲它的要求不高)。 – 2010-06-02 14:47:36

+0

他說尺寸>我,所以它沒有超出範圍。 – 2010-06-02 14:48:27

+0

@Ben,@Matt:是的,謝謝。我誤解了不平等的方向:)。 – kennytm 2010-06-02 14:50:48

4
  1. 它返回一個參考。
  2. 不,因爲矢量具有隨機存取。但是,您可以爲其他類型(例如,list,這是一個雙向鏈表)
  3. 統一所有集合(以及其他類型,如數組)。這樣,您可以在符合要求的任何類型上使用algorithms,如std::copy
1
  1. Workd因爲[]操作過載:

    參考操作符[](SIZE_TYPE N)

參見http://www.sgi.com/tech/stl/Vector.html

  • 使用迭代器遍歷STL中的任何集合都是事實。

  • 我認爲一個好處是,如果您將vector換成另一個集合,您的所有代碼都將繼續工作。

  • 0

    std :: vector是一種提供恆定時間隨機訪問的序列。您可以在常量時間通過引用訪問任何項目的引用,但是在插入和刪除矢量時付費,因爲這些操作可能是非常昂貴的操作。訪問矢量內容時不需要使用迭代器,但它支持它們。

    3

    關於你的第二點,慣用的C++方法根本不是循環的,而是使用算法(如果可行的話)。

    手冊循環輸出:

    for (std::vector<std::string>::iterator it = vec.begin(); it != end(); ++it) 
    { 
        std::cout << *it << "\n"; 
    } 
    

    算法:

    std::copy(vec.begin(), vec.end(), 
          std::ostream_iterator<std::string>(std::cout, "\n")); 
    

    手冊循環調用一個成員函數:

    for (std::vector<Drawable*>::iterator it = vec.begin(); it != end(); ++it) 
    { 
        (*it)->draw(); 
    } 
    

    算法:

    std::for_each(vec.begin(), vec.end(), std::mem_fun(&Drawable::draw)); 
    

    希望有幫助。

    1
    1. 這就是矢量的思想,它們提供對所有項目的直接訪問,就像常規數組一樣。在內部,向量表示爲動態分配的連續內存區域。 operator []被定義爲模仿常規數組的語義。

    2. 有是不是真的需要一個迭代器,你不妨使用一個索引變量去從0v_strMtVector.size()-1,因爲你將與規則的陣列做:

      for (int i = 0; i < v_strMtVector.size(); ++i) { 
          ... 
      } 
      

      也就是說,使用迭代器被許多人認爲是一種很好的風格,因爲...

    3. 使用迭代器可以更容易地替換基礎容器類型,例如從std::vector<>std::list<>。迭代器也可以用於STL算法,比如std :: sort()。