名稱空間
變體
操作

std::static_pointer_cast, std::dynamic_pointer_cast, std::const_pointer_cast, std::reinterpret_pointer_cast

來自 cppreference.com
 
 
記憶體管理庫
(僅作說明*)
未初始化記憶體演算法
(C++17)
(C++17)
(C++17)
受約束的未初始化
記憶體演算法
C 庫

分配器
記憶體資源
垃圾回收支援
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
(C++11)(直到 C++23)
未初始化儲存
(直到 C++20*)
(直到 C++20*)
顯式生命週期管理
 
 
定義於標頭檔案 <memory>
template< class T, class U >
std::shared_ptr<T> static_pointer_cast( const std::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( const std::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( const std::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( const std::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_pointer_cast 執行的 dynamic_cast 返回空指標,則它為空。

Ytypename std::shared_ptr<T>::element_type,則得到的 std::shared_ptr 的儲存指標將分別透過評估獲得:

1,2) static_cast<Y*>(r.get())
3,4) dynamic_cast<Y*>(r.get())。如果 dynamic_cast 的結果為空指標值,則返回的 shared_ptr 將為空。
5,6) const_cast<Y*>(r.get())
7,8) reinterpret_cast<Y*>(r.get())

除非從 U*T* 的相應轉換形式良好,否則這些函式的行為是未定義的。

1,2) 除非 static_cast<T*>((U*)nullptr) 形式良好,否則行為是未定義的。
3,4) 除非 dynamic_cast<T*>((U*)nullptr) 形式良好,否則行為是未定義的。
5,6) 除非 const_cast<T*>((U*)nullptr) 形式良好,否則行為是未定義的。
7,8) 除非 reinterpret_cast<T*>((U*)nullptr) 形式良好,否則行為是未定義的。

呼叫右值過載 (2,4,6,8) 後,r 為空,且 r.get() == nullptr,除了如果 dynamic_cast 失敗,則 dynamic_pointer_cast (4) 不會修改 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(const std::shared_ptr<U>& r) noexcept
{
    auto p = static_cast<typename std::shared_ptr<T>::element_type*>(r.get());
    return std::shared_ptr<T>{r, p};
}
dynamic_pointer_cast
template<class T, class U>
std::shared_ptr<T> dynamic_pointer_cast(const std::shared_ptr<U>& r) noexcept
{
    if (auto p = dynamic_cast<typename std::shared_ptr<T>::element_type*>(r.get()))
        return std::shared_ptr<T>{r, p};
    else
        return std::shared_ptr<T>{};
}
const_pointer_cast
template<class T, class U>
std::shared_ptr<T> const_pointer_cast(const std::shared_ptr<U>& r) noexcept
{
    auto p = const_cast<typename std::shared_ptr<T>::element_type*>(r.get());
    return std::shared_ptr<T>{r, p};
}
reinterpret_pointer_cast
template<class T, class U>
std::shared_ptr<T> reinterpret_pointer_cast(const std::shared_ptr<U>& r) noexcept
{
    auto p = reinterpret_cast<typename std::shared_ptr<T>::element_type*>(r.get());
    return std::shared_ptr<T>{r, p};
}

[編輯] 示例

#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>();
    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 hierarchy
    auto downcastedPtr = std::dynamic_pointer_cast<Derived>(basePtr);
    if (downcastedPtr)
    {
        std::cout << "Downcasted pointer says: ";
        downcastedPtr->f();
    }
 
    // All pointers to derived share ownership
    std::cout << "Pointers to underlying derived: "
              << derivedPtr.use_count()
              << '\n';
}

輸出

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

[編輯] 參閱

構造新的 shared_ptr
(公共成員函式) [編輯]