Почему пример ниже выводит 6?
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
static int cnt;
A(int a){}
~A(){cnt++;}
};
int A::cnt = 0;
int main()
{
vector <A> a(4,1);
a.push_back(1);
cout << A::cnt;
//cout << a.size();
}
Если убрать push_back, то выводит 1. Верно я понимаю, что вектор при инициализации и добавлении элементов выделяет в куче память для них, создаёт каждый элемент по отдельности, копирует его в это место и удаляет из этого места?
Зачем так сложно? Почему он сразу не создаст эти элементы в выделенной для себя памяти?
И даже если я верно сформулировал мысль, не понимаю, почему в 1м примере результат = 6, а не 5
Для создания вектора вы воспользовались конструктром
vector(size_type count, сonst T& value, const Allocator& alloc = Allocator());
то есть ваше
vector <A> a(4, 1);
эквивалентно
vector <A> a(4, A(1), std::allocator<A>());
Последующее уничтожение неявно созданного вами временного объекта A(1)
дало вам первый вызов деструктора.
Для добавления нового элемента в вектор вы сделали
a.push_back(1);
что эквивалентно
a.push_back(A(1));
Уничтожение этого временного объекта A(1)
дало вам еще один вызов деструктора.
При добавлении объекта в вектор произошло перевыделение памяти вектора с перемещением содержимого уже существовавших четырех объектов на новое место, после чего старые объекты были уничтожены. Это еще 4 вызова деструкторов.
Итого - 6 вызовов деструкторов.
Зачем так сложно? Почему он сразу не создаст эти элементы в выделенной для себя памяти?
А почему именно так? Здесь возможны две очевидные стратегии: 1) использовать предоставленный инициализатор 1
для независимого создания 4 целевых объектов A
, 2) сначала создать самостоятельный временный объект-образец типа A
, а затем скопировать его 4 раза в вектор.
Кто вам сказал, что первый способ лучше второго? Дизайнеры стандартной библиотеки считают по-другому. (Или по крайней мере вынужденно считали тогда, когда в С++ не было средств форвардинга аргументов.) Очевидно, что при более-менее "тяжелой" конструкции, проще сконструировать сложный объект один раз и потом несколько раз скопировать готовое, чем снова и снова конструировать объекты с нуля.
Когда же вы добавляли один-единственный элемент в вектор, никто вас не заставлял идти по пути push_back
с созданием промежуточного объекта. Вы могли сделать
a.emplace_back(1);
и действительно создать новый объект напрямую на месте.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Не получается вернуть массив через функциюЯ создал функцию, которая создает массив и заполняет все его элементы двойками, но не могу вернуть...
Подскажите как исправить следующую ошибку:
Подскажите пожалуйста, если у меня есть контейнер и я знаю сколько в нем примерно будет элементов, для ускорения работы я могу выделить их изначально,...