C++11 智能指针的Cast

一 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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C++中,智能指针类型之间的转换可以通过以下几种方式实现: 1. 隐式转换:如果两个智能指针类型具有相同的底层指针类型,可以直接进行隐式转换。例如,可以将`shared_ptr`隐式转换为`unique_ptr`。 ```cpp std::shared_ptr<int> sharedPtr = std::make_shared<int>(10); std::unique_ptr<int> uniquePtr = sharedPtr; // 隐式转换 ``` 2. 显式转换:可以使用`static_pointer_cast`、`dynamic_pointer_cast`和`const_pointer_cast`等函数进行显式类型转换。 - `static_pointer_cast`用于在两个相关类型之间进行转换,不会进行运行时类型检查。 - `dynamic_pointer_cast`用于在两个相关类型之间进行转换,并进行运行时类型检查。如果转换失败,返回空指针。 - `const_pointer_cast`用于在智能指针之间进行const或volatile修饰符的转换。 ```cpp std::shared_ptr<Base> sharedPtr = std::make_shared<Derived>(); std::shared_ptr<Derived> derivedPtr = std::dynamic_pointer_cast<Derived>(sharedPtr); // 显式转换 ``` 3. 使用`get`函数:智能指针的`get`函数可以获取底层的原始指针,从而进行类型转换。但请注意,这种方式不会管理资源的生命周期,需要自行确保资源的释放。 ```cpp std::shared_ptr<Base> sharedPtr = std::make_shared<Derived>(); Derived* derivedPtr = static_cast<Derived*>(sharedPtr.get()); // 使用get函数进行类型转换 ``` 需要注意的是,在进行智能指针类型转换时,请确保转换的正确性,以避免潜在的内存安全问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值