news 2026/6/13 20:39:17

c++智能指针转化:static_pointer_cast、dynamic_pointer_cast、const_pointer_cast、reinterpret_pointer_cast 相关函数梳

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
c++智能指针转化:static_pointer_cast、dynamic_pointer_cast、const_pointer_cast、reinterpret_pointer_cast 相关函数梳


当我们用“裸”指针进行类层次上的上下行转换时,可以使用dynamic_cast。当然我们也可以使用static_cast,只是dynamic_cast在进行下行转换的时候(即基类到派生类)具有类型检查功能,而static_cast没有。因此存在安全问题。

当我们使用智能指针时,如果需要进行类层次上的上下行转换时,可以使用std::static_pointer_cast()、std::dynamic_pointer_cast、std::const_pointer_cast()和std::reinterpret_pointer_cast()。它们的功能和std::static_cast()、std::dynamic_cast、std::const_cast()和std::reinterpret_cast()类似,只不过转换的是智能指针std::shared_ptr,返回的也是std::shared_ptr类型。

1、std::static_pointer_cast():当指针是智能指针时候,向上转换,用static_cast 则转换不了,此时需要使用static_pointer_cast。

2、std::dynamic_pointer_cast():当指针是智能指针时候,向下转换,用dynamic_cast 则转换不了,此时需要使用dynamic_pointer_cast(此处注意:base基类需要至少有一个virtual成员函数(即多态类型)才能允许动态强制转换,否则编译报错)。

3、std::const_pointer_cast():功能与std::const_cast()类似

4、std::reinterpret_pointer_cast():功能与std::reinterpret_cast()类似

Defined in header <memory>


template< class T, class U >
std::shared_ptr<T> static_pointer_cast( const std::shared_ptr<U>& r ) noexcept;

(1) (since C++11)
template< class T, class U >
std::shared_ptr<T> static_pointer_cast( std::shared_ptr<U>&& r ) noexcept;

(2) (since C++20)
template< class T, class U >
std::shared_ptr<T> dynamic_pointer_cast( const std::shared_ptr<U>& r ) noexcept;

(3) (since C++11)
template< class T, class U >
std::shared_ptr<T> dynamic_pointer_cast( std::shared_ptr<U>&& r ) noexcept;

(4) (since C++20)
template< class T, class U >
std::shared_ptr<T> const_pointer_cast( const std::shared_ptr<U>& r ) noexcept;

(5) (since C++11)
template< class T, class U >
std::shared_ptr<T> const_pointer_cast( std::shared_ptr<U>&& r ) noexcept;

(6) (since C++20)
template< class T, class U >
std::shared_ptr<T> reinterpret_pointer_cast( const std::shared_ptr<U>& r ) noexcept;

(7) (since C++17)
template< class T, class U >
std::shared_ptr<T> reinterpret_pointer_cast( std::shared_ptr<U>&& r ) noexcept;

(8) (since C++20)
基类和派生类的智能指针转换要使用std::dynamic_pointer_cast和std::static_pointer_cast。由于std::dynamic_pointer_cast和dynamic_cast原理一样,std::static_pointer_cast和static_cast原理一样

Creates a new instance of std::shared_ptr whose stored pointer is obtained from r's stored pointer using a cast expression.

If r is empty, so is the new shared_ptr (but its stored pointer is not necessarily null). Otherwise, the new shared_ptr will share ownership with the initial value of r, except that it is empty if the dynamic_cast performed by dynamic_pointer_cast returns a null pointer.

Let Y be typename std::shared_ptr<T>::element_type, then the resulting std::shared_ptr's stored pointer will be obtained by evaluating, respectively:

1-2) static_cast<Y*>(r.get()).

3-4) dynamic_cast<Y*>(r.get()) (If the result of the dynamic_cast is a null pointer value, the returned shared_ptr will be empty.)

5-6) const_cast<Y*>(r.get()).

7-8) reinterpret_cast<Y*>(r.get())

The behavior of these functions is undefined unless the corresponding cast from U* to T* is well formed:

1-2) The behavior is undefined unless static_cast<T*>((U*)nullptr) is well formed.

3-4) The behavior is undefined unless dynamic_cast<T*>((U*)nullptr) is well formed.

5-6) The behavior is undefined unless const_cast<T*>((U*)nullptr) is well formed.

7-8) The behavior is undefined unless reinterpret_cast<T*>((U*)nullptr) is well formed.

After calling the rvalue overloads (2,4,6,8), r is empty and r.get() == nullptr, except that r is not modified for dynamic_pointer_cast (4) if the dynamic_cast fails.

(since C++20)
Parameters
r - The pointer to convert
Notes
The expressions std::shared_ptr<T>(static_cast<T*>(r.get())), std::shared_ptr<T>(dynamic_cast<T*>(r.get())) and std::shared_ptr<T>(const_cast<T*>(r.get())) might seem to have the same effect, but they all will likely result in undefined behavior, attempting to delete the same object twice!

Possible implementation
1、std::static_pointer_cast():

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、std::dynamic_pointer_cast()

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、std::const_pointer_cast()

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、std::reinterpret_pointer_cast()

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"; } Output: 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 示例2 #include <iostream> // std::cout std::endl #include <memory> // std::shared_ptr std::dynamic_pointer_cast std::static_pointer_cast class base { public: virtual ~base(void) = default; }; class derived : public base { }; class test : public base { }; int main(void) { std::cout << std::boolalpha; // 两个不同的派生类对象 auto derivedobj = std::make_shared<derived>(); auto testobj = std::make_shared<test>(); // 隐式转换 derived->base std::shared_ptr<base> pointer1 = derivedobj; // static_pointer_cast derived->base auto pointer2 = std::static_pointer_cast<base>(derivedobj); // dynamic_pointer_cast base->derived auto pointer3 = std::dynamic_pointer_cast<derived>(pointer1); std::cout << (pointer3 == nullptr) << std::endl; // dynamic_pointer_cast base->derived auto pointer4 = std::dynamic_pointer_cast<test>(pointer1); std::cout << (pointer4 == nullptr) << std::endl; return 0; }


输出结果:

false
true


std::reinterpret_pointer_cast()和std::const_pointer_cast()示例代码:

#include <memory> #include <cassert> #include <cstdint> int main() { std::shared_ptr<int> foo; std::shared_ptr<const int> bar; foo = std::make_shared<int>(10); bar = std::const_pointer_cast<const int>(foo); std::cout << "*bar: " << *bar << std::endl; *foo = 20; std::cout << "*bar: " << *bar << std::endl; std::shared_ptr<std::int8_t[]> p(new std::int8_t[4]{1, 1, 1, 1}); std::shared_ptr<std::int32_t[]> q = std::reinterpret_pointer_cast<std::int32_t[]>(p); std::int32_t r = q[0]; std::int32_t x = (1 << 8) | (1 << 16) | (1 << 24) | 1; assert(r == x); return 0; }


输出:

*bar: 10
*bar: 20

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 12:55:31

Day16 ROC曲线和PR曲线

浙大疏锦行 一、前置代码 # 先运行之前预处理好的代码 import pandas as pd import pandas as pd #用于数据处理和分析&#xff0c;可处理表格数据。 import numpy as np #用于数值计算&#xff0c;提供了高效的数组操作。 import matplotlib.pyplot as plt #用于绘…

作者头像 李华
网站建设 2026/6/11 15:17:13

机器学习——决策树

决策树是一种直观且易于解释的监督学习算法&#xff0c;广泛应用于分类和回归任务。它通过模拟人类决策过程&#xff0c;将复杂问题拆解为一系列简单的判断规则&#xff0c;最终形成类似 “树” 状的结构。以下从基础概念、原理、算法类型、优缺点及应用场景等方面展开详细介绍…

作者头像 李华
网站建设 2026/6/10 21:57:24

Rotation Pro 强制转屏工具体验:精准控制每个应用的屏幕方向

应用背景与核心价值 在使用安卓手机时&#xff0c;不少用户可能遇到过这样的困扰&#xff1a;部分应用&#xff08;如特定视频播放器、阅读工具或旧版游戏&#xff09;本应支持横屏显示&#xff0c;却无法正常旋转屏幕&#xff0c;即便系统已开启自动旋转功能。这一问题不仅影…

作者头像 李华
网站建设 2026/6/13 13:43:46

企业级滑雪场管理系统管理系统源码|SpringBoot+Vue+MyBatis架构+MySQL数据库【完整版】

摘要 随着滑雪运动的普及和滑雪旅游产业的快速发展&#xff0c;传统滑雪场管理模式在效率、安全性和用户体验方面逐渐暴露出诸多不足。滑雪场管理涉及场地预约、设备租赁、会员管理、教练服务等多个环节&#xff0c;传统人工管理方式不仅效率低下&#xff0c;且容易因信息不对称…

作者头像 李华
网站建设 2026/6/12 11:04:39

创客匠人:决定未来三年企业生死的,是你的智能体

未来三年&#xff0c;企业增长的核心命题已经悄然改变。过去&#xff0c;我们追逐流量、粉丝、曝光&#xff1b;但今天&#xff0c;我们越来越清晰地看到&#xff1a;真正决定企业生死的&#xff0c;不再是涨粉&#xff0c;而是你是否拥有自己的智能体。AI不再只是一种工具&…

作者头像 李华