C ++ векторные идеи - PullRequest
       42

C ++ векторные идеи

2 голосов
/ 02 июня 2010

Я немного разочарован тем, как использовать векторы в C ++. Я использую их широко, хотя я не совсем уверен, как я их использую. Ниже приведены вопросы?

  1. Если у меня есть вектор, скажем: std::vector<CString> v_strMyVector, с (int)v_strMyVector.size > i я могу получить доступ к члену i: v_strMyVector[i] == "xxxx";? (хотя почему?)

  2. Нужно ли мне всегда определять итератор для доступа к началу вектора и переходить к его элементам?

  3. Какова цель итератора, если у меня есть доступ ко всем членам вектора напрямую (см. 1)?

Заранее спасибо, Вс

Ответы [ 6 ]

10 голосов
/ 02 июня 2010
  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)
    ...
    

    нам просто нужно N шаблонов

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

    и каждый из контейнера M предоставляет итераторы, сокращая количество необходимых функций до просто M + N.

4 голосов
/ 02 июня 2010
  1. Возвращает ссылку.
  2. Нет ,, потому что вектор имеет произвольный доступ. Тем не менее, вы делаете для других типов (например, список , который является двусвязным списком)
  3. Для объединения всех коллекций (наряду с другими типами, например, массивами). Таким образом, вы можете использовать алгоритмы , такие как std :: copy для любого типа, который соответствует требованиям.
3 голосов
/ 02 июня 2010

Что касается вашего второго пункта, идиоматический способ 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 голос
/ 02 июня 2010
  1. Это идея векторов, они обеспечивают прямой доступ ко всем элементам, как и обычные массивы. Внутри векторы представляются как динамически распределяемые непрерывные области памяти. operator [] определено для имитации семантики регулярного массива.

  2. Наличие итератора на самом деле не требуется, вы также можете использовать индексную переменную, которая изменяется от 0 до v_strMtVector.size()-1, как вы это делаете с обычным массивом:

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

    Тем не менее, использование итератора считается хорошим стилем для многих, потому что ...

  3. Использование итератора облегчает замену базового типа контейнера, например, от std::vector<> до std::list<>. Итераторы также могут использоваться с алгоритмами STL, такими как std :: sort ().
1 голос
/ 02 июня 2010
  1. Работает, потому что оператор [] перегружен:

    оператор ссылки [] (size_type n)

См. http://www.sgi.com/tech/stl/Vector.html

  1. Обход любой коллекции в STL с использованием итератора де-факто.

  2. Я думаю, что одним из преимуществ является то, что если вы замените vector другим набором, весь ваш код продолжит работать.

0 голосов
/ 02 июня 2010

std :: vector - тип последовательности, обеспечивающей произвольный доступ с постоянным временем. Вы можете получить доступ к ссылке на любой элемент по ссылке в постоянном времени, но вы платите за нее при вставке и удалении из вектора, поскольку это может быть очень дорогой операцией. Вам не нужно использовать итераторы при доступе к содержимому вектора, но он поддерживает их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...