|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
| Modifiers | ||||
| Observers | ||||
(C++17) | ||||
(until C++20*) | ||||
(C++26) | ||||
(C++26) | ||||
| Non-member functions | ||||
static_pointer_castdynamic_pointer_castconst_pointer_castreinterpret_pointer_cast (C++17) | ||||
(until C++20)(until C++20)(until C++20)(until C++20)(until C++20)(C++20) | ||||
functions(until C++26*) | ||||
| Helper classes | ||||
(C++20) | ||||
| Deduction guides(C++17) |
Defined in header <memory> | ||
template<class T,class U> std::shared_ptr<T> static_pointer_cast(conststd::shared_ptr<U>& r)noexcept; | (1) | (since C++11) |
template<class T,class U> std::shared_ptr<T> static_pointer_cast(std::shared_ptr<U>&& r)noexcept; | (2) | (since C++20) |
template<class T,class U> std::shared_ptr<T> dynamic_pointer_cast(conststd::shared_ptr<U>& r)noexcept; | (3) | (since C++11) |
template<class T,class U> std::shared_ptr<T> dynamic_pointer_cast(std::shared_ptr<U>&& r)noexcept; | (4) | (since C++20) |
template<class T,class U> std::shared_ptr<T> const_pointer_cast(conststd::shared_ptr<U>& r)noexcept; | (5) | (since C++11) |
template<class T,class U> std::shared_ptr<T> const_pointer_cast(std::shared_ptr<U>&& r)noexcept; | (6) | (since C++20) |
template<class T,class U> std::shared_ptr<T> reinterpret_pointer_cast(conststd::shared_ptr<U>& r)noexcept; | (7) | (since C++17) |
template<class T,class U> std::shared_ptr<T> reinterpret_pointer_cast(std::shared_ptr<U>&& r)noexcept; | (8) | (since C++20) |
Creates a new instance ofstd::shared_ptr whose stored pointer is obtained fromr's stored pointer using a cast expression.
Ifr is empty, so is the newshared_ptr (but its stored pointer is not necessarily null). Otherwise, the newshared_ptr will share ownership with the initial value ofr, except that it is empty if thedynamic_cast performed bydynamic_pointer_cast returns a null pointer.
LetY betypenamestd::shared_ptr<T>::element_type, then the resultingstd::shared_ptr's stored pointer will be obtained by evaluating, respectively:
dynamic_cast is a null pointer value, the returnedshared_ptr will be empty.The behavior of these functions is undefined unless the corresponding cast fromU* toT* is well formed:
After calling the rvalue overloads(2,4,6,8),r is empty andr.get()== nullptr, except thatr is not modified for | (since C++20) |
Contents |
| r | - | the pointer to convert |
The expressionsstd::shared_ptr<T>(static_cast<T*>(r.get())),std::shared_ptr<T>(dynamic_cast<T*>(r.get())) andstd::shared_ptr<T>(const_cast<T*>(r.get())) might seem to have the same effect, but they all will likely result in undefined behavior, attempting to delete the same object twice!
| 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<<"I am base!\n";}virtual ~Base(){}}; class Derived:public Base{public:void f()const override{std::cout<<"I am derived!\n";} ~Derived(){}}; int main(){auto basePtr=std::make_shared<Base>();std::cout<<"Base pointer says: "; basePtr->f(); auto derivedPtr=std::make_shared<Derived>();std::cout<<"Derived pointer says: "; derivedPtr->f(); // static_pointer_cast to go up class hierarchy basePtr= std::static_pointer_cast<Base>(derivedPtr);std::cout<<"Base pointer to derived says: "; basePtr->f(); // dynamic_pointer_cast to go down/across class hierarchyauto downcastedPtr= std::dynamic_pointer_cast<Derived>(basePtr);if(downcastedPtr){std::cout<<"Downcasted pointer says: "; downcastedPtr->f();} // All pointers to derived share ownershipstd::cout<<"Pointers to underlying derived: "<< derivedPtr.use_count()<<'\n';}
Output:
Base pointer says: I am base!Derived pointer says: I am derived!Base pointer to derived says: I am derived!Downcasted pointer says: I am derived!Pointers to underlying derived: 3
constructs newshared_ptr(public member function)[edit] |