2016-08-18 8 views
3

I (ошибочно) было следующее задание в моей программе:Назначение make_unique <X> к shared_ptr <X>

std::shared_ptr<SI::Program> m_program; // in class 

m_program = std::make_unique<SI::Program>(); // in method 

Когда я нашел это, я первым задавался вопросом, почему это даже компилирует. Оказывается, shared_ptr имеет специальный оператор назначения перемещения для объектов unique_ptr.

Мой вопрос в том, что это всегда безопасно, или это имеет какие-либо последствия?

(Safe, как и для выполнения кода, это, очевидно, не безопасно для проверки кода ...)

+0

Одной из причин этого может быть использование специализированной специализации 'unique_ptr', которой' shared_ptr' не хватает. [Это * * создает проблему безопасности.] (Http://stackoverflow.com/questions/32483375/shared-ptr-from-unique-ptr-to-an-array) – jaggedSpire

ответ

2

Это «безопасно», чтобы сделать это в некотором смысле, что у вас не будет двойных удалений или других проблем.

Это не нормально, чтобы сделать это, потому что:

  1. Это заблуждение - make_unique используется, чтобы сделать уникальные указатели, а не общие.
  2. Это расточительно - make_unique будет выделять объект, а не соответствующий блок управления. что заставит конструктор shared_ptr выделить сам блок управления. std::make_shared выделяют их как в одном распределении, что намного эффективнее.
+1

"* Это вводит в заблуждение - используется make_unique чтобы сделать уникальные указатели, а не разделять. * «Если комитет сочтет ошибочным, чтобы иметь возможность обновлять уникальное право собственности на совместное владение, они не дали бы' shared_ptr' конкретному конструктору делать именно это. –

+1

@NicolBolas Обновление обычно может быть в порядке, но, как и я, оно имеет определенный коэффициент WTF –

3

Да, это совершенно безопасно; shared_ptr имеет конструктор, который может передать право собственности с unique_ptr путем перемещения. Хотя это не так эффективно, как правильно позвонить make_shared.