Подтвердить что ты не робот

Почему пустой вектор вызывает конструктор по умолчанию типа по умолчанию?

Используя g++, я замечаю, что создание вектора нулевого размера вызывает один раз конструктор типа объекта с параметрическим параметрированием. Затем он удаляется. Почему это происходит?

#include <iostream>
#include <vector>
using namespace std;

class s
{
    public:
    s() { cout << endl << "default s constructor" << endl; }
    ~s() { cout << endl << "default s destructor" << endl; }

};

int main()
{
    vector<s> v(0);
}

Вывод:

конструктор по умолчанию

деструктор по умолчанию

4b9b3361

Ответ 1

Потому что вы явно передаете начальный размер, который вызывает конструктор с другим параметром, значение по умолчанию которого s(). Просто оставьте (0) (т.е. std::vector<s> v;), и этого не произойдет.

Для полноты, стандарт 23.2.4-2 определяет конструктор, который вы вызываете как:

    explicit vector(size_type n, const T& value = T() ,
                                    const Allocator& = Allocator());

Кроме того (относится к С++ 03, но не к С++ 11)

Еще один интересный поведенческий аспект этого конструктора также поднимает голову на S.O. периодически: когда исходное число запрошенных элементов составляет > 0, оно копирует эти элементы из прототипального параметра в конструктор:

  • люди часто помещают конструктор по умолчанию, который оставляет переменные-члены неинициализированными, надеясь сделать vector(n) почти так же быстро, как базовое свободное распределение хранилища, НО
  • экземпляр-копия по-прежнему вызывается n раз, чтобы скопировать содержимое "мусора" прототипа в каждый из запрошенных элементов.

Это имеет очевидную стоимость исполнения, но также может привести к сбою приложения, если содержимое мусора включает, например, действительны только указатели, которые может использовать только конструктор-копир. Точно так же это чрезвычайно опасно для даже push_back такого неинициализированного объекта мусора - ему не хватает правильной семантической инкапсуляции значения и может быть скопировано по мере изменения вектора, алгоритмические операции, такие как std::sort() выполняются на векторе и т.д.

Ответ 2

Фактический конструктор, который вы вызываете, - (cplusplus.com):

explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );

Таким образом, хотя вы указываете только размер, для второго параметра создается новый объект T и поэтому также будет уничтожен по завершении конструктора.