2010-06-02 102 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()。