Почему / когда я должен использовать std :: unique / shared_ptr (std :: vector <>) вместо просто std :: vector <>? - PullRequest
0 голосов
/ 08 марта 2019

Меня немного смущает основное использование std::unique/shared_ptr(std::vector<>), когда я могу просто использовать std::vector<>, который, как я знаю, сам по себе является динамическим массивом. Как я уже видел, люди говорят, что между этими двумя показателями нет никакой разницы в производительности. Итак, на основании всего этого, какой смысл использовать умный указатель, указывающий на контейнер (в данном случае на вектор) вместо одного вектора?

1 Ответ

2 голосов
/ 08 марта 2019

Прежде всего, вы не должны использовать std::shared_ptr, если вам не нужна особая семантика "совместного владения", связанная с std::shared_ptr. Если вам нужен умный указатель, вы должны по умолчанию использовать std::unique_ptr по умолчанию и переключаться с него только в том сценарии, где вы явно обнаружите, что вам нужно.

Во-вторых: якобы , причина, по которой вы предпочитаете std::unique_ptr<TYPE>, а не TYPE, заключается в том, что вы планируете много перемещать объект. Это общая парадигма проектирования для больших объектов, которые либо неподвижны, либо иным образом дороги в перемещении, т.е. они реализовали конструктор копирования и не реализовали конструктор перемещения, поэтому движения вынуждены вести себя как копия.

std::vector, однако, имеет относительно эффективную семантику перемещения: если вы перемещаете std::vector, независимо от того, насколько сложными являются содержащиеся в нем типы, перемещение представляет собой только пару обменов указателей. Нет реального риска, что перемещение std::vector повлечет за собой большую вычислительную сложность. Даже в сценарии, где вы переопределяете ранее выделенный массив (вызывая деструкторы всех объектов в векторе), у вас все равно будет такая сложность, если вы вместо этого будете использовать std::unique_ptr<std::vector<TYPE>>, ничего не экономя.

У std::unique_ptr<std::vector<TYPE>> есть два преимущества. Первый из них заключается в том, что он избавляется от неявного конструктора копирования; может быть, вы хотите заставить программистов поддерживать, чтобы объект не копировался. Но это довольно нишевое использование. Другое преимущество состоит в том, что он позволяет вам задавать сценарий, в котором нет вектора, то есть vec.size() == 0 - это другое условие, чем doesNotExist(vec). Но даже в этом сценарии вы должны предпочесть std::optional<std::vector> вместо этого, что лучше передает через код намерение объекта. Конечно, std::optional доступен только в C ++ 17 → Code, так что, возможно, вы находитесь в среде, которая еще не реализовала это. Но в остальном нет особых причин использовать std::unique_ptr<std::vector>.

В общем, я не верю, что есть практическое применение для std::unique_ptr<std::vector>. Практической разницы в производительности между ним и std::vector нет, и его использование просто сделает ваш код излишне сложным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...