Как shared_ptr может нарушить выравнивание
Я читаю документы по DirectXMath и наткнулся на следующий отрывок:
В качестве альтернативы принудительному выравниванию в вашем классе C++ путем перегрузки new/delete вы можете использовать идиому pImpl. Если вы убедитесь, что ваш класс Impl выровнен с помощью __aligned_malloc, вы можете свободно использовать выровненные типы во внутренней реализации. Это хороший вариант, когда открытый класс является ссылочным классом среды выполнения Windows или предназначен для использования с std::shared_ptr<>, который в противном случае может нарушить тщательное выравнивание.
Я не понимаю, как shared_ptr может делать какие-либо изменения в стратегии выравнивания, у него есть только указатель, он не выделяет объект.
1 ответ
Ты прав, std::shared_ptr
не влияет на выравнивание. Он просто получает указатель на уже выделенный объект, поэтому, если это распределение привело к смещенному объекту, проблема не в std::shared_ptr
С этим распределением.
Но std::shared_ptr
часто используется с std::make_shared
, std::make_shared<T>
выполняет одно выделение резервной памяти как для std::shared_ptr
структура управления и T
пример. Это распределение не сделано с использованием какого-либо конкретного класса operator new
(и не должно быть). Если для конкретного класса operator new
устанавливает более строгое выравнивание чем то, что делает распределитель по умолчанию, тогда легко видеть, как это может потерпеть неудачу, когда распределитель по умолчанию используется.
Вот почему иногда навязчивый счетчик ссылок предпочтительнее std::shared_ptr, вы можете явно объявить требование выравнивания для своего класса.
Также не забудьте объявить деструктор частным, чтобы запретить (де) размещение в стеке.