Мой вопрос:
(а) почему конструктор копирования вызывается так часто?
Потому что при изменении размера вектора вам нужно скопировать все элементы из старого буфера в новый буфер. Это потому, что вектор гарантирует, что объекты хранятся в последовательных ячейках памяти.
(b) есть ли способ избежать использования конструктора копирования, если вы просто двигаетесь
объект из одного места в другое?
Нет, нет способа избежать использования конструктора копирования.
Это потому, что объект имеет несколько членов, которые должны быть правильно инициализированы.
Если вы использовали memcpy, как узнать, что объект был правильно инициализирован для объекта!
Например. ЕСЛИ объект содержал умный указатель. Вы не можете просто запоминать умный указатель. Нужно сделать дополнительную работу, чтобы отследить право собственности. В противном случае, когда оригинал выходит из области видимости, память удаляется, а новый объект имеет висячий указатель. Тот же принцип применим ко всем объектам, у которых есть конструктор (конструктор копирования), который конструктор действительно требует требуемой работы.
Способ остановить копирование содержимого слишком зарезервировать место.
Это заставляет вектор выделять достаточно места для всех объектов, которые он будет хранить. Таким образом, нет необходимости постоянно перераспределять основной буфер. Он просто копирует объекты в вектор.
Удвоение каждый раз должно вызывать конструктор копирования 64 раза.
Если вы очень обеспокоены сохранением низкого уровня использования памяти, то увеличивайте на
50% каждый раз должны вызывать конструктор копирования 121 раз.
Так откуда взялись 177?
Вектор выделенного размера = 1:
Добавить элемент 1: (без перераспределения) Но копирует элемент 1 в вектор.
Добавить элемент 2: перераспределить буфер (размер 2): скопировать элемент 1 поперек. Скопируйте элемент 2 в вектор.
Добавить элемент 3: перераспределить буфер (размер 4): скопировать элемент 1-2 поперек. Скопируйте элемент 3 в вектор.
Добавьте элемент 4: скопируйте элемент 4 в вектор
Добавить элемент 5: перераспределить буфер (размер 8): скопировать элемент 1-4 поперек. Скопируйте элемент 5 в вектор.
Добавить элемент 6: скопировать элемент 6 в вектор
Добавьте элемент 7: скопируйте элемент 7 в вектор
Добавить элемент 8: скопировать элемент 8 в вектор
Добавить элемент 9: перераспределить буфер (размер 16): скопировать элемент 1-8 поперек. Скопируйте элемент 9 в вектор.
Добавьте элемент 10: скопируйте элемент 10 в вектор
и т. д.
Первые 10 элементов заняли 25 копий конструкций.
Если бы вы сначала использовали резерв, то потребовалось бы всего 10 копий конструкций.