Конструктор для вектора c

Обновлено: 01.05.2024

Vectors are sequence containers representing arrays that can change in size.

Just like arrays, vectors use contiguous storage locations for their elements, which means that their elements can also be accessed using offsets on regular pointers to its elements, and just as efficiently as in arrays. But unlike arrays, their size can change dynamically, with their storage being handled automatically by the container.

Internally, vectors use a dynamically allocated array to store their elements. This array may need to be reallocated in order to grow in size when new elements are inserted, which implies allocating a new array and moving all elements to it. This is a relatively expensive task in terms of processing time, and thus, vectors do not reallocate each time an element is added to the container.

Instead, vector containers may allocate some extra storage to accommodate for possible growth, and thus the container may have an actual capacity greater than the storage strictly needed to contain its elements (i.e., its size). Libraries can implement different strategies for growth to balance between memory usage and reallocations, but in any case, reallocations should only happen at logarithmically growing intervals of size so that the insertion of individual elements at the end of the vector can be provided with amortized constant time complexity (see push_back).

Therefore, compared to arrays, vectors consume more memory in exchange for the ability to manage storage and grow dynamically in an efficient way.

Compared to the other dynamic sequence containers (deques, lists and forward_lists), vectors are very efficient accessing its elements (just like arrays) and relatively efficient adding or removing elements from its end. For operations that involve inserting or removing elements at positions other than the end, they perform worse than the others, and have less consistent iterators and references than lists and forward_lists.

Container properties

Sequence Elements in sequence containers are ordered in a strict linear sequence. Individual elements are accessed by their position in this sequence. Dynamic array Allows direct access to any element in the sequence, even through pointer arithmetics, and provides relatively fast addition/removal of elements at the end of the sequence. Allocator-aware The container uses an allocator object to dynamically handle its storage needs.

Template parameters

T Type of the elements.
Only if T is guaranteed to not throw while moving, implementations can optimize to move elements instead of copying them during reallocations.
Aliased as member type vector::value_type. Alloc Type of the allocator object used to define the storage allocation model. By default, the allocator class template is used, which defines the simplest memory allocation model and is value-independent.
Aliased as member type vector::allocator_type.

Member types

member typedefinitionnotes
value_typeThe first template parameter (T)
allocator_typeThe second template parameter (Alloc)defaults to: allocator
referenceallocator_type::referencefor the default allocator: value_type&
const_referenceallocator_type::const_referencefor the default allocator: const value_type&
pointerallocator_type::pointerfor the default allocator: value_type*
const_pointerallocator_type::const_pointerfor the default allocator: const value_type*
iteratora random access iterator to value_typeconvertible to const_iterator
const_iteratora random access iterator to const value_type
reverse_iteratorreverse_iterator
const_reverse_iteratorreverse_iterator
difference_typea signed integral type, identical to: iterator_traits::difference_typeusually the same as ptrdiff_t
size_typean unsigned integral type that can represent any non-negative value of difference_typeusually the same as size_t
member typedefinitionnotes
value_typeThe first template parameter (T)
allocator_typeThe second template parameter (Alloc)defaults to: allocator
referencevalue_type&
const_referenceconst value_type&
pointerallocator_traits::pointerfor the default allocator: value_type*
const_pointerallocator_traits::const_pointerfor the default allocator: const value_type*
iteratora random access iterator to value_typeconvertible to const_iterator
const_iteratora random access iterator to const value_type
reverse_iteratorreverse_iterator
const_reverse_iteratorreverse_iterator
difference_typea signed integral type, identical to:
iterator_traits::difference_type
usually the same as ptrdiff_t
size_typean unsigned integral type that can represent any non-negative value of difference_typeusually the same as size_t

Member functions

(constructor) Construct vector (public member function ) (destructor) Vector destructor (public member function ) operator= Assign content (public member function )
Iterators:
begin Return iterator to beginning (public member function ) end Return iterator to end (public member function ) rbegin Return reverse iterator to reverse beginning (public member function ) rend Return reverse iterator to reverse end (public member function ) cbegin Return const_iterator to beginning (public member function ) cend Return const_iterator to end (public member function ) crbegin Return const_reverse_iterator to reverse beginning (public member function ) crend Return const_reverse_iterator to reverse end (public member function )
Capacity:
size Return size (public member function ) max_size Return maximum size (public member function ) resize Change size (public member function ) capacity Return size of allocated storage capacity (public member function ) empty Test whether vector is empty (public member function ) reserve Request a change in capacity (public member function ) shrink_to_fit Shrink to fit (public member function )
Element access:
operator[] Access element (public member function ) at Access element (public member function ) front Access first element (public member function ) back Access last element (public member function ) data Access data (public member function )
Modifiers:
assign Assign vector content (public member function ) push_back Add element at the end (public member function ) pop_back Delete last element (public member function ) insert Insert elements (public member function ) erase Erase elements (public member function ) swap Swap content (public member function ) clear Clear content (public member function ) emplace Construct and insert element (public member function ) emplace_back Construct and insert element at the end (public member function )
Allocator:
get_allocator Get allocator (public member function )

Non-member function overloads

relational operators Relational operators for vector (function template ) swap Exchange contents of vectors (function template )

The elements are stored contiguously, which means that elements can be accessed not only through iterators, but also using offsets to regular pointers to elements. This means that a pointer to an element of a vector may be passed to any function that expects a pointer to an element of an array.

The storage of the vector is handled automatically, being expanded and contracted as needed. Vectors usually occupy more space than static arrays, because more memory is allocated to handle future growth. This way a vector does not need to reallocate each time an element is inserted, but only when the additional memory is exhausted. The total amount of allocated memory can be queried using capacity() function. Extra memory can be returned to the system via a call to shrink_to_fit() . (since C++11)

Reallocations are usually costly operations in terms of performance. The reserve() function can be used to eliminate reallocations if the number of elements is known beforehand.

The complexity (efficiency) of common operations on vectors is as follows:

  • Random access - constant 𝓞(1)
  • Insertion or removal of elements at the end - amortized constant 𝓞(1)
  • Insertion or removal of elements - linear in the distance to the end of the vector 𝓞(n)

Member functions of std::vector are constexpr : it is possible to create and use std::vector objects in the evaluation of a constant expression.

However, std::vector objects generally cannot be constexpr , because any dynamically allocated storage must be released in the same evaluation of constant expression.

Contents

[edit] Template parameters

The requirements that are imposed on the elements depend on the actual operations performed on the container. Generally, it is required that element type meets the requirements of Erasable , but many member functions impose stricter requirements. This container (but not its members) can be instantiated with an incomplete element type if the allocator satisfies the allocator completeness requirements.

[edit] Specializations

The standard library provides a specialization of std::vector for the type bool , which may be optimized for space efficiency.

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

Быстрый переход по статье:

Что такое вектор (vector)

Вектор — это структура данных, которая уже является моделью динамического массива.

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

Как создать вектор (vector) в C++

Сначала для создания вектора нам понадобится подключить библиотеку — , в ней хранится шаблон вектора.

Кстати, сейчас и в будущем мы будем использовать именно шаблон вектора. Например, очередь или стек, не созданные с помощью массива или вектора, тоже являются шаблонными.

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

  • Вначале пишем слово vector .
  • Далее в угольных скобках указываем тип, которым будем заполнять ячейки.
  • И в самом конце указываем имя вектора.

В примере выше мы создали вектор строк.

Кстати, заполнить вектор можно еще при инициализации (другие способы мы пройдем позже — в методах вектора). Делается это также просто, как и в массивах. Вот так:

После имени вектора ставим знак равенства и скобки, в которых через пробел указываем значение элементов.

Такой способ инициализации можно использовать только в C++!

Так, чтобы заполнить вектор строками, нам нужно использовать кавычки — "строка" .

Второй способ обратиться к ячейке

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

Но в C++ есть еще один способ это сделать благодаря функции — at(). В скобках мы должны указать индекс той ячейки, к которой нужно обратиться.

Вот как она работает на практике:

Давайте запустим эту программу:

Как указать количество ячеек для вектора

Указывать размер вектора можно по-разному. Можно это сделать еще при его инициализации, а можно хоть в самом конце программы. Вот, например, способ указать длину вектора на старте:

Так в круглых скобках () после имени вектора указываем первоначальную длину. А вот второй способ:

Первая строчка нам уже знакома. А вот во второй присутствует незнакомое слово — reserve , это функция, с помощью которой мы говорим компилятору, какое количество ячеек нам нужно использовать.

Вы можете задать логичный вопрос:»А в чем разница?». Давайте создадим два вектора и по-разному укажем их количество ячеек.

Как видим, в первом случае мы вывели три нуля, а во втором: 17, 0, 0.

Все потому, что при использовании первого способа все ячейки автоматически заполнились нулями.

При объявлении чего-либо (массива, вектора, переменной и т.д) мы выделяем определенное количество ячеек памяти, в которых уже хранится ненужный для ПК мусор. В нашем случае этим мусором являются числа.

Поэтому, когда мы вывели второй вектор, в нем уже находились какие-то рандомные числа — 17, 0, 0. Обычно они намного больше. Можете кстати попробовать создать переменную и вывести ее значение.

Нужно помнить! При использовании второго способа есть некоторый плюс — по времени. Так как для первого способа компилятор тратит время, чтобы заполнить все ячейки нулями.


Как сравнить два вектора

Если в середине программы нам понадобиться сравнить два массива, мы, конечно, используем цикл for и поочередно проверим все элементы.

Вектор снова на шаг впереди! Чтобы нам сравнить два вектора, потребуется применить всего лишь оператор ветвления if.

Для добавления элементов в вектор применяется функция push_back() , в который передается добавляемый элемент:

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

Функция emplace_back() выполняет аналогичную задачу - добавляет элемент в конец контейнера:

Добавление элементов на определенную позицию

Ряд функций позволяет добавлять элементы на определенную позицию.

emplace(pos, value) : вставляет элемент value на позицию, на которую указывает итератор pos

insert(pos, value) : вставляет элемент value на позицию, на которую указывает итератор pos, аналогично функции emplace

insert(pos, n, value) : вставляет n элементов value начиная с позиции, на которую указывает итератор pos

insert(pos, begin, end) : вставляет начиная с позиции, на которую указывает итератор pos, элементы из другого контейнера из диапазона между итераторами begin и end

insert(pos, values) : вставляет список значений начиная с позиции, на которую указывает итератор pos

Удаление элементов

Если необходимо удалить все элементы вектора, то можно использовать функцию clear :

Функция pop_back() удаляет последний элемент вектора:

Если нужно удалить элемент из середины или начала контейнера, применяется функция erase() , которая имеет следующие формы:

erase(p) : удаляет элемент, на который указывает итератор p. Возвращает итератор на элемент, следующий после удаленного, или на конец контейнера, если удален последний элемент

erase(begin, end) : удаляет элементы из диапазона, на начало и конец которого указывают итераторы begin и end. Возвращает итератор на элемент, следующий после последнего удаленного, или на конец контейнера, если удален последний элемент

Размер вектора

С помощью функции size() можно узнать размер вектора, а с помощью функции empty() проверить, путой ли вектор:

С помощью функции resize() можно изменить размер вектора. Эта функция имеет две формы:

resize(n) : оставляет в векторе n первых элементов. Если вектор содержит больше элементов, то его размер усекается до n элементов. Если размер вектора меньше n, то добавляются недостающие элементы и инициализируются значением по умолчанию

resize(n, value) : также оставляет в векторе n первых элементов. Если размер вектора меньше n, то добавляются недостающие элементы со значением value

Важно учитывать, что применение функции resize может сделать некорректными все итераторы, указатели и ссылки на элементы.

Изменение элементов вектора

Функция assign() позволяет заменить все элементы вектора определенным набором:

В данном случае элементы вектора заменяются набором из четырех строк "Sam".

Еще одна функция - swap() обменивает значения двух контейнеров:

Сравнение векторов

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

Constructs a vector, initializing its contents depending on the constructor version used:

(1) empty container constructor (default constructor) Constructs an empty container, with no elements. (2) fill constructor Constructs a container with n elements. Each element is a copy of val. (3) range constructor Constructs a container with as many elements as the range [first,last), with each element constructed from its corresponding element in that range, in the same order. (4) copy constructor Constructs a container with a copy of each of the elements in x, in the same order.
The container keeps an internal copy of alloc, which is used to allocate storage throughout its lifetime.
The copy constructor (4) creates a container that keeps and uses a copy of x's allocator.

The storage for the elements is allocated using this internal allocator.

(1) empty container constructor (default constructor) Constructs an empty container, with no elements. (2) fill constructor Constructs a container with n elements. Each element is a copy of val (if provided). (3) range constructor Constructs a container with as many elements as the range [first,last), with each element emplace-constructed from its corresponding element in that range, in the same order. (4) copy constructor (and copying with allocator) Constructs a container with a copy of each of the elements in x, in the same order. (5) move constructor (and moving with allocator) Constructs a container that acquires the elements of x.
If alloc is specified and is different from x's allocator, the elements are moved. Otherwise, no elements are constructed (their ownership is directly transferred).
x is left in an unspecified but valid state. (6) initializer list constructor Constructs a container with a copy of each of the elements in il, in the same order.
The container keeps an internal copy of alloc, which is used to allocate and deallocate storage for its elements, and to construct and destroy them (as specified by its allocator_traits). If no alloc argument is passed to the constructor, a default-constructed allocator is used, except in the following cases:
- The copy constructor (4, first signature) creates a container that keeps and uses a copy of the allocator returned by calling the appropriate selected_on_container_copy_construction trait on x's allocator.
- The move constructor (5, first signature) acquires x's allocator.

All elements are copied, moved or otherwise constructed by calling allocator_traits::construct with the appropriate arguments.

Parameters

alloc Allocator object.
The container keeps and uses an internal copy of this allocator.
Member type allocator_type is the internal allocator type used by the container, defined in vector as an alias of its second template parameter (Alloc).
If allocator_type is an instantiation of the default allocator (which has no state), this is not relevant. n Initial container size (i.e., the number of elements in the container at construction).
Member type size_type is an unsigned integral type. val Value to fill the container with. Each of the n elements in the container will be initialized to a copy of this value.
Member type value_type is the type of the elements in the container, defined in vector as an alias of its first template parameter (T). first, last Input iterators to the initial and final positions in a range. The range used is [first,last), which includes all the elements between first and last, including the element pointed by first but not the element pointed by last.
The function template argument InputIterator shall be an input iterator type that points to elements of a type from which value_type objects can be constructed. x Another vector object of the same type (with the same class template arguments T and Alloc), whose contents are either copied or acquired.
il An initializer_list object.
These objects are automatically constructed from initializer list declarators.
Member type value_type is the type of the elements in the container, defined in vector as an alias of its first template parameter (T).

Example

Complexity

Constant for the default constructor (1), and for the move constructors (5) (unless alloc is different from x's allocator).
For all other cases, linear in the resulting container size.
Additionally, if InputIterator in the range constructor (3) is not at least of a forward iterator category (i.e., it is just an input iterator), the new capacity cannot be determined beforehand and the construction incurs in additional logarithmic complexity in size (reallocations while growing).

Iterator validity

The move constructors (5), invalidate all iterators, pointers and references related to x if the elements are moved.

Data races

Exception safety

Strong guarantee: no effects in case an exception is thrown.
If allocator_traits::construct is not supported with the appropriate arguments for the element constructions, or if the range specified by [first,last) is not valid, it causes undefined behavior.

See also

vector::operator= Assign content (public member function ) vector::assign Assign vector content (public member function ) vector::reserve Request a change in capacity (public member function ) vector::resize Change size (public member function ) vector::clear Clear content (public member function )

Читайте также: