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

来自cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
工具库
类型支持(基本类型、 RTTI 、类型特性)
动态内存管理
错误处理
程序工具
变参数函数
日期和时间
函数对象
(C++11)
关系运算符
optionalanyvariant (C++17)
pair 与 tuple
(C++11)
(C++17)
swap 、 forward 与 move
(C++14)
(C++11)
(C++11)
初等字符串转换
(C++17)
(C++17)
类型运算
(C++11)
(C++17)
 
动态内存管理
 
 
定义于头文件 <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 起)

创建 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) 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*的对应转型为良式:

1) 行为未定义,除非 static_cast<T*>((U*)nullptr) 为良式。
2) 行为未定义,除非 dynamic_cast<T*>((U*)nullptr) 为良式。
3) 行为未定义,除非 const_cast<T*>((U*)nullptr) 为良式。
4) 行为未定义,除非 reinterpret_cast<T*>((U*)nullptr) 为良式。

目录

[编辑] 参数

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())) 看起来可能拥有相同效果,但它们全都很可能导致未定义行为,试图删除同一对象二次!

[编辑] 可能的实现

版本一
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);
}
版本二
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>();
    }
}
版本三
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);
}

[编辑] 示例

#include <iostream>
#include <memory>
 
struct BaseClass {};
 
struct DerivedClass : BaseClass
{
    void f() const
    {
        std::cout << "Hello World!\n";
    }
    ~DerivedClass(){ // note, it's not virtual
        std::cout << "~DerivedClass\n";
    }
};
 
int main()
{
    std::shared_ptr<BaseClass> ptr_to_base(std::make_shared<DerivedClass>());
 
    // ptr_to_base->f(); // 错误不会编译: BaseClass 无名为 'f' 的成员
 
    std::static_pointer_cast<DerivedClass>(ptr_to_base)->f(); // OK
    // (构造临时 shared_ptr ,然后调用 operator-> )
 
    static_cast<DerivedClass*>(ptr_to_base.get())->f(); // also OK
    // (直接转型,不构造临时 shared_ptr )
}

输出:

Hello World!
Hello World!
~DerivedClass

[编辑] 参阅

构造新的 shared_ptr
(公开成员函数) [编辑]