allocate_shared
, make_shared
и make_unique
все инициализируют базовый объект, выполняя что-то эквивалентное new T(args...)
.В случае с нулевым аргументом, который уменьшается до new T()
, то есть он выполняет инициализацию значения .Инициализация значений во многих случаях (включая скалярные типы, такие как int
и char
, их массивы и их совокупности) выполняет нулевую инициализацию - то естьфактическая работа выполняется для обнуления группы данных.
Может быть, вы хотите это, и это важно для вашего приложения, а может, нет.Начиная с P1020R1 , бумаги, в которой были представлены make_unique_default_init
, make_shared_default_init
и allocate_shared_default_init
:
Это не редкость для массивов встроенных типов, таких как unsigned char
или double
для немедленной инициализации пользователем полностью после выделения.В этих случаях инициализация значений, выполняемая allocate_shared
, make_shared
и make_unique
, является избыточной и снижает производительность, и необходим способ выбора инициализации по умолчанию.
То есть, есливы писали код вроде:
auto buffer = std::make_unique<char[]>(100);
read_data_into(buffer.get());
Инициализация значения, выполняемая make_unique
, которая обнуляет эти 100 байтов, совершенно не нужна, так как вы все равно немедленно перезаписываете ее.
Новые функции meow_default_init
вместо этого выполняют инициализацию по умолчанию (отсюда и название) - что эквивалентно действию new T
(без скобок и скобок).Инициализация по умолчанию в тех случаях, о которых я упоминал ранее (например, int
и char
, их массивы и их совокупности), не выполняет инициализацию, что экономит время.
Для типов классов, которые имеют предоставленный пользователем конструктор по умолчанию, нет никакой разницы между инициализацией значения и инициализацией по умолчанию: оба просто вызовут конструктор по умолчанию.Но для многих других типов может быть большая разница.