C : вызывается дополнительный конструктор копирования

#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. спасибо за объяснение!