#c #copy-constructor
#c #конструктор копирования
Вопрос:
понимая концепцию конструктора копирования, я не могу объяснить вывод отладки следующей простой тестовой программы:
#include <iostream>
#include <vector>
using std::cout, std::endl, std::vector;
class Module
{
private:
char *name;
public:
// ctor
Module(char n);
// copy ctor
Module(const Module amp;m);
// dtor
~Module();
};
Module::Module(char n)
{
name = new char;
*name = n;
cout << "ctor " << n << endl;
}
// copy ctor
Module::Module(const Module amp;m)
: Module{*m.name}
{
cout << "copy ctr " << *name << endl;
}
Module::~Module()
{
if (name != nullptr)
{
cout << "dtor " << *name << endl;
}
delete name;
}
int main()
{
vector<Module> vec;
vec.push_back(Module{'A'});
vec.push_back(Module{'B'});
return 0;
}
его вывод:
ctor A ctor A copy ctr A dtor A ctor B ctor B copy ctr B ctor A copy ctr A dtor A dtor B dtor A dtor B
Я ожидал следующего вывода:
ctor A ctor A copy ctr A dtor A ctor B ctor B copy ctr B dtor B dtor A dtor B
если кто-нибудь знает, я хотел бы знать причину такого поведения…
g .exe (Rev5, созданный проектом MSYS2) 10.2.0
заранее спасибо!
Комментарии:
1. Похоже, вы предполагаете, что память (и объекты) выделяются конструктором vectors .
push_back()
также может перераспределяться.
Ответ №1:
Когда вы добавляете элементы в свой вектор, он может быть перераспределен. Это означает, что выделяется новая память, и элементы копируются из старой памяти в новую память. Этот процесс вызывает конструктор копирования.
Чтобы предотвратить перераспределение, заранее зарезервируйте необходимую память.
vector<Module> vec;
vec.reserve(2);
vec.push_back(Module{'A'});
vec.push_back(Module{'B'});
Примечание (поскольку его часто неправильно понимают) reserve
не изменяет размер вектора, оно просто выделяет больше памяти, чтобы вектор мог расти без необходимости перераспределения.
Комментарии:
1. это имеет смысл, я забыл о проблеме, заключающейся в том, что vector динамически выделяет память при push_back. спасибо за объяснение!