shared_ptr_pointer_cast

shared_ptr_pointer_cast (shared_ptr 캐스트)

<memory> 헤더에 정의되어 있어요. r의 저장된 포인터를 캐스트 표현식으로 변환해 얻은 새 저장 포인터를 가진 std::shared_ptr 객체를 생성해요. static_cast·dynamic_cast·const_cast·reinterpret_cast에 대응하는 shared_ptr 버전이에요.

출처: cppreference

본문

template< class T, class U >
std::shared_ptr<T> static_pointer_cast( const std::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( const std::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( const std::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( const std::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

r의 저장된 포인터를 캐스트 표현식으로 변환해 얻은 새 std::shared_ptr 객체를 생성해요.

  • r이 비어 있으면 새 shared_ptr도 비어요(단 저장된 포인터가 널일 필요는 없음).
  • 그 외에는 dynamic_pointer_cast가 수행하는 dynamic_cast가 널 포인터를 돌려주지 않는 한, 새 shared_ptrr의 초기값과 소유권을 공유해요.

std::shared_ptr<T>(/* ***_cast */<T*>(r.get()))는 같은 효과처럼 보이지만 같은 객체를 두 번 delete하는 미정의 동작을 초래할 수 있어요. rvalue 오버로드(2,4,6,8) 호출 후 r은 비어 있고 r.get() == nullptr이에요.

예제

#include <iostream>
#include <memory>

class Base
{
public:
    int a;
    virtual void 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>();
    auto derivedPtr = std::make_shared<Derived>();

    basePtr = std::static_pointer_cast<Base>(derivedPtr);   // 업캐스트
    auto downcastedPtr = std::dynamic_pointer_cast<Derived>(basePtr);  // 다운캐스트
    if (downcastedPtr)
        downcastedPtr->f();
    std::cout << "Pointers to underlying derived: "
              << derivedPtr.use_count() << '\n';
}

출력:

Downcasted pointer says: I am derived!
Pointers to underlying derived: 3

더 알아보기 (Learn more)

cppreference