名前空間
変種
操作

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

提供: cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
 
動的メモリ管理
未初期化記憶域
(C++17)
ガベージコレクションサポート
その他
(C++20)
(C++11)
(C++11)
C のライブラリ
低水準のメモリ管理
 
 
ヘッダ <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> dynamic_pointer_cast( const std::shared_ptr<U>& r ) noexcept;
(2) (C++11およびそれ以降)
template< class T, class U >
std::shared_ptr<T> const_pointer_cast( const std::shared_ptr<U>& r ) noexcept;
(3) (C++11およびそれ以降)
template< class T, class U >
std::shared_ptr<T> reinterpret_pointer_cast( const std::shared_ptr<U>& r ) noexcept;
(4) (C++17およびそれ以降)

r の格納されているポインタからキャスト式を使用して取得したポインタを格納する新しい std::shared_ptr のインスタンスを作成します。 r が空であれば、新しい shared_ptr も空になります (格納されるポインタがヌルになるとは限りません)。

そうでなければ、新しい shared_ptrr と所有権を共有します。 ただし、 dynamic_pointer_cast によって行われる dynamic_cast がヌルポインタを返した場合は空になります。

Ytypename std::shared_ptr<T>::element_type とすると、結果の std::shared_ptr に格納されるポインタはそれぞれ以下を評価することによって取得されます。

1) static_cast<Y*>(r.get())
2) dynamic_cast<Y*>(r.get()) (dynamic_cast の結果がヌルポインタ値の場合、返される shared_ptr は空になります)
3) const_cast<Y*>(r.get())
4) reinterpret_cast<Y*>(r.get())

U* から T* への対応するキャストが well-formed でなければ、これらの関数の動作は未定義です。

1) static_cast<T*>((U*)nullptr) が well-formed でなければ、動作は未定義です。
2) dynamic_cast<T*>((U*)nullptr) が well-formed でなければ、動作は未定義です。
3) const_cast<T*>((U*)nullptr) が well-formed でなければ、動作は未定義です。
4) reinterpret_cast<T*>((U*)nullptr) が well-formed でなければ、動作は未定義です。

目次

[編集] 引数

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())) も同じ効果を持つように見えるかもしれませんが、これらはすべて、同じオブジェクトの delete を2回試みることによる未定義動作になりがちです。

[編集] 実装例

1つめのバージョン
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);
}
2つめのバージョン
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>();
    }
}
3つめのバージョン
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);
}
4つめのバージョン
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>
 
struct Base 
{ 
    int a; 
    virtual void f() const { std::cout << "I am base!\n";}
    virtual ~Base(){}
};
 
struct Derived : Base
{
    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 を構築します
(パブリックメンバ関数) [edit]