Конвертировать unique_ptr <Derived>в unique_ptr <Base> - PullRequest
0 голосов
/ 06 июля 2018

Простой код

class Base {};
class Derived : Base {};

unique_ptr<Base> Create() {
    unique_ptr<Base> basePtr = make_unique<Derived>(); // compile error
    return basePtr;
}

выдает ошибку компиляции («нет подходящего преобразования»). Я нашел аналогичный вопрос , где решение заключается в использовании std::move. Я попробовал это

unique_ptr<Derived> derived = make_unique<Derived>();
unique_ptr<Base> basePtr = std::move(derived); // compile error

но теперь std::move выдает ошибку компиляции. Я также нашел вопрос , где (если я правильно понял) приведение должно быть автоматическим, если мы используем

unique_ptr<Base> basePtr = make_unique<Derived>(new Derived()); //compile error

но это также не работает (ошибка компиляции), а также не рекомендуется использовать new с умными указателями.

Какое будет правильное решение?

Единственное рабочее решение, которое я нашел до сих пор

unique_ptr<Base> basePtr = unique_ptr<Base>((Base*)new Derived());

выглядит очень некрасиво.

1 Ответ

0 голосов
/ 06 июля 2018

Ваш класс наследуется в частном порядке от базового класса. Это значение по умолчанию для class, тогда как для struct по умолчанию используется публичное наследование. Это делает внешние преобразования из базы в недействительные. unique_ptr обрабатывает преобразования из производных в базу в порядке с публичным наследованием ( живой пример ):

 class Base {};
 class Derived : public Base {};
                 ^^^^^^

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

...