Вне зависимости от того, имеет ли смысл копировать unique_ptr
или нет*, я пытался реализовать такой класс, просто обернув std::unique_ptr
, и столкнулся с трудностями именно там, где берется копия, в случае умного указателя на базу и хранимый объект является производным классом.
Наивную реализацию конструктора копирования можно найти по всему Интернету (data
— это обернутый std::unique_ptr
):
copyable_unique_ptr::copyable_unique_ptr(const copyable_unique_ptr& other)
: data(std::make_unique(*other.get()) // invoke the class's copy constructor
{}
Проблема здесь в том, что из-за опущенных аргументов шаблона копия создает экземпляр типа T
, даже если реальный тип U : T
. Это приводит к потере информации на копии, и хотя я прекрасно понимаю, почему это происходит здесь, я не могу найти способ обойти это.
Обратите внимание, что в случае перемещения проблем нет. Исходный указатель был правильно создан где-то в пользовательском коде, и его перемещение к новому владельцу не изменяет реальный тип объекта. Чтобы сделать копию, вам нужна дополнительная информация.
Также обратите внимание, что решение, использующее функцию clone
(таким образом заражающее интерфейс типа T
), не является тем, что я считаю приемлемым.
* если вам нужен единственный указатель владельца на копируемый ресурс, это может иметь смысл, и он предоставляет гораздо больше, чем то, что могут предоставить scoped_ptr
или auto_ptr
.
T
иU
. Таким образом, не заразить T напрямую. - person Hayt   schedule 24.10.2016value_ptr
. Пример реализации здесь: bitbucket.org/martinhofernandes/wheels/src/. - person rubenvb   schedule 24.10.2016reset
:/ - person rubenvb   schedule 24.10.2016