В целом, я бы выбрал решение # 1, то есть vector<MyObject>
.
Это проще, чем # 2 (vector<shared_ptr<MyObject>>
).
С # 1, вы можете иметь хороший модуля памяти локальность, поскольку MyObject
экземпляры хранятся последовательно в памяти, что очень кэш-дружественных (и так эффективно).
Вместо этого, с # 2, значения указателей сохраняются последовательно в векторе, но объекты, на которые указывает, рассеиваются в куче, поэтому у вас нет хорошей локальности в этом случае.
Однако могут быть исключения из общего правила. Например, я бы использовал опцию vector<shared_ptr<MyObject>>
, если экземпляры MyObject
тяжелы для копирования и не дешевы для перемещения. В этом случае семантика указателя может помочь.
В любом случае, если есть сомнения, меры. Если вы не уверены в производительности какого-либо кода, просто напишите тестовый код для различных параметров, которые у вас есть, и измерьте время выполнения.
Заметим также, что, если вы используете C++ 11/14, вы все равно можете иметь указатель семантику, но более эффективным способом, чем shared_ptr
: на самом деле, вы можете использовать std::unique_ptr
. unique_ptr
не имеет блока управления (типичный для shared_ptr
), не имеет взаимосвязанных операций приращения и уменьшения для счетчика ref и, как правило, быстрее и компактнее, чем shared_ptr
. Если вам не нужна семантика совместного использования, и вы можете использовать компилятор C++ 11, unique_ptr
- очень хорошая альтернатива shared_ptr
.
Заметим также, что вы можете сделать vector<shared_ptr<...>>
немного более эффективным, если вы используете правильный аллокатора для объекта: вместо того, чтобы использовать сырой new
, рассмотреть возможность использования make_shared
. Он имеет некоторые преимущества, такие как создание блока управления и объекта в последовательных ячейках памяти, поэтому у вас лучше локализация памяти, чем блок управления, созданный на куче, удаленном от управляемого объекта.
Не выделяйте динамически, если вы можете избежать этого. – Borgleader
Я готов поспорить, что даже если вы * do * должны динамически выделять, вы не должны использовать 'shared_ptr', а' unique_ptr'. –
@JohnDibling, по крайней мере, он использует интеллектуальные указатели вместо сырых. – Borgleader