std::static_pointer_cast, std::dynamic_pointer_cast, std::const_pointer_cast, std::reinterpret_pointer_cast
Определено в заголовочном файле <memory> | ||
template<class T, class U > std::shared_ptr<T> static_pointer_cast(conststd::shared_ptr<U>& r )noexcept; | (1) | (начиная с C++11) |
template<class T, class U > std::shared_ptr<T> static_pointer_cast(std::shared_ptr<U>&& r )noexcept; | (2) | (начиная с C++20) |
template<class T, class U > std::shared_ptr<T> dynamic_pointer_cast(conststd::shared_ptr<U>& r )noexcept; | (3) | (начиная с C++11) |
template<class T, class U > std::shared_ptr<T> dynamic_pointer_cast(std::shared_ptr<U>&& r )noexcept; | (4) | (начиная с C++20) |
template<class T, class U > std::shared_ptr<T> const_pointer_cast(conststd::shared_ptr<U>& r )noexcept; | (5) | (начиная с C++11) |
template<class T, class U > std::shared_ptr<T> const_pointer_cast(std::shared_ptr<U>&& r )noexcept; | (6) | (начиная с C++20) |
template<class T, class U > std::shared_ptr<T> reinterpret_pointer_cast(conststd::shared_ptr<U>& r )noexcept; | (7) | (начиная с C++17) |
template<class T, class U > std::shared_ptr<T> reinterpret_pointer_cast(std::shared_ptr<U>&& r )noexcept; | (8) | (начиная с C++20) |
Создаёт новый экземпляр std::shared_ptr, сохранённый указатель которого получается из сохранённого указателя r с помощью выражения приведения.
Если r пуст, то и новый shared_ptr
пуст (но его сохранённый указатель не обязательно нулевой). Иначе новый shared_ptr
будет разделять владение с начальным значением r, за исключением того, что он будет пустым, если dynamic_cast
, выполняемый через dynamic_pointer_cast
, возвращает нулевой указатель.
Пусть Y
будет typenamestd::shared_ptr<T>::element_type, тогда результирующий сохранённый указатель объекта std::shared_ptr будет получен путём оценки, соответственно:
dynamic_cast
является значение нулевого указателя, возвращаемый shared_ptr
будет пустым.)Поведение этих функций не определено, если только соответствующее приведение из U*
в T*
не корректно:
После вызова перегрузок rvalue (2,4,6,8), r пусто, а r.get()== nullptr, за исключением того, что r не изменяется для | (начиная с C++20) |
Содержание |
[править]Параметры
r | — | Указатель для преобразования |
[править]Примечание
Выражения std::shared_ptr<T>(static_cast<T*>(r.get())), std::shared_ptr<T>(dynamic_cast<T*>(r.get())) и std::shared_ptr<T>(const_cast<T*>(r.get())) могут показаться одинаковыми, но все они, скорее всего, приведут к неопределённому поведение, при попытке удалить один и тот же объект дважды!
[править]Возможная реализация
static_pointer_cast |
---|
template<class T, class U >std::shared_ptr<T> static_pointer_cast(conststd::shared_ptr<U>& r )noexcept{auto p =static_cast<typenamestd::shared_ptr<T>::element_type*>(r.get());returnstd::shared_ptr<T>{r, p};} |
dynamic_pointer_cast |
template<class T, class U >std::shared_ptr<T> dynamic_pointer_cast(conststd::shared_ptr<U>& r )noexcept{if(auto p =dynamic_cast<typenamestd::shared_ptr<T>::element_type*>(r.get()))returnstd::shared_ptr<T>{r, p};elsereturnstd::shared_ptr<T>{};} |
const_pointer_cast |
template<class T, class U >std::shared_ptr<T> const_pointer_cast(conststd::shared_ptr<U>& r )noexcept{auto p =const_cast<typenamestd::shared_ptr<T>::element_type*>(r.get());returnstd::shared_ptr<T>{r, p};} |
reinterpret_pointer_cast |
template<class T, class U >std::shared_ptr<T> reinterpret_pointer_cast(conststd::shared_ptr<U>& r )noexcept{auto p =reinterpret_cast<typenamestd::shared_ptr<T>::element_type*>(r.get());returnstd::shared_ptr<T>{r, p};} |
[править]Пример
#include <iostream>#include <memory> class Base {public:int a;virtualvoid f()const{std::cout<<"Я базовый!\n";}virtual ~Base(){}}; class Derived :public Base {public:void f()const override {std::cout<<"Я производный!\n";} ~Derived(){}}; int main(){auto basePtr =std::make_shared<Base>();std::cout<<"Базовый указатель говорит: "; basePtr->f(); auto derivedPtr =std::make_shared<Derived>();std::cout<<"Производный указатель говорит: "; derivedPtr->f(); // static_pointer_cast для перехода вверх по иерархии классов basePtr = std::static_pointer_cast<Base>(derivedPtr);std::cout<<"Базовый указатель в производный говорит: "; basePtr->f(); // dynamic_pointer_cast для перехода вниз/поперёк иерархии классовauto downcastedPtr = std::dynamic_pointer_cast<Derived>(basePtr);if(downcastedPtr){std::cout<<"Приведённый вниз указатель говорит: "; downcastedPtr->f();} // Все указатели на производное общее владениеstd::cout<<"Указатели на производные: "<< derivedPtr.use_count()<<'\n';}
Вывод:
Базовый указатель говорит: Я базовый! Производный указатель говорит: Я производный! Базовый указатель в производный говорит: Я производный! Приведённый вниз указатель говорит: Я производный! Указатели на производные: 3
[править]Смотрите также
создаёт новый shared_ptr (public функция-элемент) |