C++11 智能指针的Cast

本文详细介绍了C++11及以后版本中智能指针的转换方法,包括static_pointer_cast, dynamic_pointer_cast, const_pointer_cast和reinterpret_pointer_cast的使用,对比了C++11之前的转换方式,展示了如何在继承层次结构中进行指针转换,并提供了具体示例。

一 C++11前

在C++11之前,对智能指针转换的方法大概如下:

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())) 

但它们有可能导致未定义行为,即删除同一对象两次。

二 C++11

C++11开始引入了std::static_pointer_cast,std::dynamic_pointer_cast,std::const_pointer_cast。(std::reinterpret_pointer_cast在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> 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 起)

特别是C++20中引入的右值引入版本,除了(4)若dynamic_cast失败不会更改r,(2)(6)(8)调用后,r为空且r.get() == nullptr 

三 举例

#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"; 
}

 结果:

四 参考

cppreference

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值