Приведение типов умных указателей C++

297
06 января 2018, 03:15

А можно ли привести тип умного указателя родительского класса к дочернему? К примеру есть есть базовый класс Models и от него наследуется класс Staff. Вот сам пример:

void StaffsModel::addItem(std::shared_ptr<Models> item)
{
    std::shared_ptr<Staff> ptrStaff = (std::shared_ptr<Staff>)item;
    Staff *newStaff = ptrStaff.get();
    ...
}
Answer 1

Приводить тип std::shared_ptr можно при помощи специальных функций:

  • std::static_pointer_cast - аналог static_cast
  • std::dynamic_pointer_cast - аналог dynamic_cast
  • std::const_pointer_cast - аналог const_cast

То что вы хотите сделать называется "понижающее приведение типа". Его возможно выполнить через static_cast, но безопаснее будет использовать dynamic_cast.

void StaffsModel::addItem(std::shared_ptr<Models> item){
    std::shared_ptr<Staff> ptrStaff = std::dynamic_pointer_cast<Staff>(item);
    Staff *newStaff = ptrStaff.get();
    //...
}

PS: Конкретно в вашем примере не вижу никаких препятствий сделать

void StaffsModel::addItem(std::shared_ptr<Models> item){
    Staff *newStaff = dynamic_cast<Staff*>(item.get());
    //...
}
Answer 2

Для преобразования shared_ptr имеются функции:
std::static_pointer_cast - подобие static_cast
std::dynamic_pointer_cast - подобие dynamic_cast
std::const_pointer_cast - подобие const_cast

std::shared_ptr<Staff> ptrStaff = std::static_pointer_cast<Staff>(item);
std::shared_ptr<Staff> ptrStaff = std::dynamic_pointer_cast<Staff>(item);
Answer 3

Получилось вот так, может кому-нибудь пригодится

std::shared_ptr<Staff> ptrStaff = std::static_pointer_cast<Staff>(item)
Staff *newStaff = ptrStaff.get();
Answer 4

Нет смысла делать еще один локальный умный указатель, просто приводите по ссылке:

auto newStaff{dynamic_cast<Staff *>(item.get())};

Если же хочется именно еще один умный указатель, то следует использовать dynamic_pointer_cast:

auto ptrStaff{::std::dynamic_pointer_cast<Staff>(item)};

И в том, и в другом случае получившийся указатель может быть нулевым и его обязательно следует проверить перед использованием. Кроме того, для работы dynamic_cast должна быть включена поддержка рантайм информации о типах.

READ ALSO
Связные списки в с++

Связные списки в с++

Очень сложно разобраться со связными списками( Помогите разобраться в этой части кода,пожалуйста:

350
Содержимое указателя

Содержимое указателя

Немного запутался:

235
Поиск максимальной суммы в подмассиве

Поиск максимальной суммы в подмассиве

Дан массив, требуется найти такой подмассив с максимальной суммой элементов в нем, чтобы начало и конец отрезка были одинаковыми(вывести...

265