Категории
Самые читаемые
Лучшие книги » Компьютеры и Интернет » Программирование » Язык программирования C++. Пятое издание - Стенли Липпман

Язык программирования C++. Пятое издание - Стенли Липпман

Читать онлайн Язык программирования C++. Пятое издание - Стенли Липпман

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 31 32 33 34 35 36 37 38 39 ... 297
Перейти на страницу:

Для создания экземпляра шаблона класса следует указать дополнительную информацию, характер которой зависит от шаблона. Эта информация всегда задается одинаково: в угловых скобках после имени шаблона.

В случае вектора предоставляемой дополнительной информацией является тип объектов, которые он должен содержать:

vector<int> ivec;             // ivec содержит объекты типа int

vector<Sales_item> Sales_vec; // содержит объекты класса Sales_item

vector<vector<string>> file;  // вектор, содержащий другие векторы

В этом примере компилятор создает три разных экземпляра шаблона vector: vector<int>, vector<Sales_item> и vector<vector<string>>.

vector — это шаблон, а не класс. Классам, созданным по шаблону vector, следует указать тип хранимого элемента, например vector<int>.

Можно определить векторы для содержания объектов практически любого типа. Поскольку ссылки не объекты (см. раздел 2.3.1), не может быть вектора ссылок. Однако векторы большинства других (не ссылочных) встроенных типов и типов классов вполне могут существовать. В частности, может быть вектор, элементами которого являются другие векторы.

Следует заметить, что прежние версии языка С++ использовали несколько иной синтаксис определения вектора, элементы которого сами являлись экземплярами шаблона vector (или другого типа шаблона). Прежде необходимо было ставить пробел между закрывающей угловой скобкой внешней части vector и типом его элемента: т.е. vector<vector<int> >, а не vector<vector<int>>.

Некоторые компиляторы могут потребовать объявления вектора векторов в старом стиле, например vector<vector<int> >.

3.3.1. Определение и инициализация векторов

Подобно любому типу класса, шаблон vector контролирует способ определения и инициализации векторов. Наиболее распространенные способы определения векторов приведены в табл. 3.4.

Инициализация вектора по умолчанию (см. раздел 2.2.1) позволяет создать пустой вектор определенного типа:

vector<string> svec; // инициализация по умолчанию;

                     // у svec нет элементов

Могло бы показаться, что пустой вектор бесполезен. Однако, как будет продемонстрировано вскоре, элементы в вектор можно без проблем добавлять и во время выполнения. В действительности наиболее распространенный способ использования векторов подразумевает определение первоначально пустого вектора, в который элементы добавляются по мере необходимости во время выполнения.

Таблица 3.4. Способы инициализации векторов

vector<T> v1 Вектор, содержащий объекты типа T. Стандартный конструктор v1 пуст vector<T> v2(v1) Вектор v2 — копия всех элементов вектора v1 vector<T> v2 = v1 Эквивалент v2(v1), v2 — копия элементов вектора v1 vector<T> v3(n, val) Вектор v3 содержит n элементов со значением val vector<T> v4(n) Вектор v4 содержит n экземпляров объекта типа T, инициализированного значением по умолчанию vector<T> v5{a,b,с ...} Вектор v5 содержит столько элементов, сколько предоставлено инициализаторов; элементы инициализируются соответствующими инициализаторами vector<T> v5 = {a,b,с ... } Эквивалент v5{a,b,c ... }

При определении вектора для его элементов можно также предоставить исходное значение (или значения). Например, можно скопировать элементы из другого вектора. При копировании векторов каждый элемент нового вектора будет копией соответствующего элемента исходного. Оба вектора должны иметь тот же тип:

vector<int> ivec; // первоначально пустой

// присвоить ivec несколько значений

vector<int> ivec2(ivec);    // копировать элементы ivec в ivec2

vector<int> ivec3 = ivec;   // копировать элементы ivec в ivec3

vector<string> svec(ivec2); // svec содержит строки,

                            // а не целые числа

Списочная инициализация вектора

Согласно новому стандарту, еще одним способом предоставления значений элементам вектора является списочная инициализация (см. раздел 2.2.1), т.е. заключенный в фигурные скобки список любого количества начальных значений элементов:

vector<string> articles = {"a", "an", "the"};

В результате у вектора будет три элемента: первый со значением "а", второй — "an", последний — "the".

Как уже упоминалось, язык С++ предоставляет несколько форм инициализации (см. раздел 2.2.1). Во многих, но не во всех случаях эти формы инициализации можно использовать взаимозаменяемо. На настоящий момент приводились примеры двух форм инициализации: инициализация копией (с использованием знака =) (см. раздел 3.2.1), когда предоставляется только один инициализатор; и внутриклассовая инициализация (см. раздел 2.6.1). Третий способ подразумевает предоставление списка значений элементов, заключенных в фигурные скобки (списочная инициализация). Нельзя предоставить список инициализаторов, используя круглые скобки.

vector<string> v1{"a", "an", "the"}; // списочная инициализация

vector<string> v2("a", "an", "the"); // ошибка

Создание определенного количества элементов

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

vector<int> ivec(10, -1);       // десять элементов типа int, каждый из

                                // которых инициализирован значением -1

vector<string> svec(10, "hi!"); // десять строк, инициализированных

                                // значением "hi!"

Инициализация значения

Иногда инициализирующее значение можно пропустить и указать только размер. В этом случае произойдет инициализация значения (value initialization), т.е. библиотека создаст инициализатор элемента сама. Это созданное библиотекой значение используется для инициализации каждого элемента в контейнере. Значение инициализатора элемента вектора зависит от типа его элементов.

Если вектор хранит элементы встроенного типа, такие как int, то инициализатором элемента будет значение 0. Если элементы имеют тип класса, такой как string, то инициализатором элемента будет его значение по умолчанию.

vector<int> ivec(10);    // десять элементов, инициализированных

                         // значением 0

vector<string> svec(10); // десять элементов, инициализированных

                         // пустой строкой

Эта форма инициализации имеет два ограничения. Первое — некоторые классы всегда требуют явного предоставления инициализатора (см. раздел 2.2.1). Если вектор содержит объекты, тип которых не имеет значения по умолчанию, то начальное значение элемента следует предоставить самому; невозможно создать векторы таких типов, предоставив только размер.

Второе ограничение заключается в том, что при предоставлении количества элементов без исходного значения необходимо использовать прямую инициализацию (direct initialization):

vector<int> vi = 10; // ошибка: необходима прямая инициализация

Здесь число 10 используется для указания на то, как создать вектор, — необходимо, чтобы он обладал десятью элементами с инициализированными значениями. Число 10 не "копируется" в вектор. Следовательно, нельзя использовать форму инициализации копией. Более подробная информация об этом ограничении приведена в разделе 7.5.4.

Списочный инициализатор или количество элементов

В некоторых случаях смысл инициализации зависит от того, используются ли при передаче инициализаторов фигурные скобки или круглые. Например, при инициализации вектора vector<int> одиночным целочисленным значением это значение могло бы означать либо размер вектора, либо значение элемента. Точно так же, если предоставить два целочисленных значения, то они могли бы быть размером и исходным значением или значениями для двух элементов вектора. Для определения предназначения используются фигурные или круглые скобки.

1 ... 31 32 33 34 35 36 37 38 39 ... 297
Перейти на страницу:
На этой странице вы можете бесплатно скачать Язык программирования C++. Пятое издание - Стенли Липпман торрент бесплатно.
Комментарии