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

定义于头文件 <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
(公开成员函数)

版本历史

  • (当前 | 先前 2017年9月3日 (日) 18:04Fruderica讨论 | 贡献 . . (4,082字节) (0). . (撤销)
  • 当前 | 先前 2017年9月3日 (日) 09:52Fruderica讨论 | 贡献. . (4,082字节) (+1,924). . (撤销)
  • 当前 | 先前 2013年7月2日 (二) 09:07P12bot讨论 | 贡献 . . (2,158字节) (-108). . (Use {{lc}}. Update links. Various fixes.) (撤销)
  • 当前 | 先前 2012年11月2日 (五) 14:46P12bot讨论 | 贡献 . . (2,266字节) (+337). . (r2.7.3) (机器人添加:de, en, es, fr, it, ja, pt, ru) (撤销)
  • 当前 | 先前 2012年10月27日 (六) 03:40P12讨论 | 贡献 . . (1,929字节) (0). . (1个修订: Translate from the English version) (撤销)
  • 当前 | 先前 2012年10月26日 (五) 06:00TranslationBot讨论 | 贡献. . (1,929字节) (-35). . (Translated from the English version using Google Translate) (撤销)
  • 当前 | 先前 2012年10月25日 (四) 14:55P12讨论 | 贡献 . . (1,964字节) (0). . (1个修订: Translate from the English version) (撤销)
  • 当前 | 先前) 2012年10月25日 (四) 12:00TranslationBot讨论 | 贡献. . (1,964字节) (+1,964). . (Translated from the English version using Google Translate)