Dynamic/Static/Reinterpret/Const and Volatile Cast (English)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

Const and Volatile Cast

The expression const_cast<T>(v) can be used to change the "const" or "volatile" qualifiers of pointers or references. T must be a pointer, reference, or pointer to member type. If cv1 and cv2 are some combination of const and volatile qualifiers (that is, cv1 is volatile and cv2 is const volatile), const_cast can convert a value of type "pointer to cv1 T" to "pointer to cv2
T", or "pointer to member of type cv1 T" to "pointer to member of type cv2 T". If we have an lvalue of type cv1 T, then const_cast can convert it to "reference to type cv2 T". (An lvalue names an object in such a way that its address can be taken.)

  class A { public: virtual void f();  
                    int i; };  
  extern const int A::* cimp;  
  extern const volatile int* cvip;  
  extern int* ip;  
  void use_of_const_cast( )  
      { const A a1;  
        const_cast<A&>(a1).f( );   // remove const  
        a1.*(const_cast<int A::*> cimp) = 1;    // remove const  
        ip = const_cast<int*> cvip; }   // remove const and volatile  

Reinterpret Cast

The expression reinterpret_cast<T>(v)changes the interpretation of the value of the expression v. It will convert from pointer types to integers and back again, between two unrelated pointers, pointers to members, or pointers to functions. The only guarantee on such casts is that a cast to a new type, followed by a cast back to the original type, will have the original value. It is legal to cast an lvalue of type T1 to type T2& if a pointer of type T1* can be converted to a pointer of type T2* by a reinterpret_cast. reinterpret_cast cannot be used to convert between pointers to two different classes that are related by inheritance (use static_cast or dynamic_cast), nor can it be used to cast away const (use const_cast).

  class A { public: virtual void f( ); };  
  void use_of_reinterpret_cast( )  
      { A a1;  
        const A a2;  
        int i = reinterpret_cast<int>(&a1);   // grab address  
        const int j = reinterpret_cast<int>(&a2); }  // grab address  

Static Cast

The expression static_cast<T>(v) converts the value of the expression v to that of type T. It can be used for any cast that is performed implicitly on assignment. In addition, any value may be cast to void, and any implicit cast can be reversed if that cast would be legal as an old-style cast. It cannot be used to cast away const.

  class B            { public: virtual void g( ); };  
  class C : public B { public: virtual void g( ); };  
  
  void use_of_static_cast( )  
      { C c;  
        // an explicit temporary lvalue to the base of c, a B  
        B& br = c;  
        br.g( );   // call B::g instead of C::g  
        // a static_cast of an lvalue to the base of c, a B  
        static_cast<B&>(c).g( ); }   // call B::g instead of C::g  

Dynamic Cast

A pointer or reference to a class can actually point to any class publicly derived from that class. Occasionally, it may be desirable to obtain a pointer to the fully-derived class, or to some other base class for the object. The dynamic cast provides this facility.
The dynamic type cast will convert a pointer or reference to one class into a pointer or reference to another class. That second class must be the fully-derived class of the object, or a base class of the fully-derived class.
In the expression dynamic_cast<T>(v), v is the expression to be cast, and T is the type to which it should be cast. T must be a pointer or reference to a complete class type, or "pointer to cv void", where cv is [ const][ volatile]. In the case of pointer types, if the specified class is not a base of the fully
derived class, the cast returns a null pointer. In the case of reference types, if the specified class is not a base of the fully derived class, the cast throws a bad_cast exception. For example, given the class definitions:

  class A          { public: virtual void f( ); };  
  class B          { public: virtual void g( ); };  
  class AB :       public virtual A, private B { };  

The following function will succeed.

  void simple_dynamic_casts( )  
      { AB  ab;  
        B*  bp  = (B*)&ab;  // cast needed to break protection  
        A*  ap  = &ab;      // public derivation, no cast needed  
        AB& abr = dynamic_cast<AB&>(*bp);  // succeeds  
        ap = dynamic_cast<A*>(bp);         assert( ap != NULL );  
        bp = dynamic_cast<B*>(ap);         assert( bp == NULL );  
        ap = dynamic_cast<A*>(&abr);       assert( ap != NULL );  
        bp = dynamic_cast<B*>(&abr);       assert( bp == NULL ); }  

In the presence of virtual inheritance and multiple inheritance of a single base class, the actual dynamic cast must be able to identify a unique match. If the match is not unique, the cast fails. For example, given the additional class definitions:

  class AB_B :     public AB,        public B  { };  
  class AB_B__AB : public AB_B,      public AB { };  

The following function will succeed:

  void complex_dynamic_casts( )  
      {  
        AB_B__AB ab_b__ab;  
        A*ap = &ab_b__ab;  
                      // okay: finds unique A statically  
        AB*abp = dynamic_cast<AB*>(ap);  
                      // fails: ambiguous  
        assert( abp == NULL );  
               // STATIC ERROR: AB_B* ab_bp = (AB_B*)ap;  
                      // not a dynamic cast  
        AB_B*ab_bp = dynamic_cast<AB_B*>(ap);  
                      // dynamic one is okay  
        assert( ab_bp != NULL );  
       }  

The null-pointer error return of dynamic_cast is useful as a condition between two bodies of code, one to handle the cast if the type guess is correct, and one if it is not.

  void using_dynamic_cast( A* ap )  
      {  
        if ( AB *abp = dynamic_cast<AB*>(ap) )  
            { // abp is non-null,  
              // so ap was a pointer to an AB object  
              // go ahead and use abp  
              process_AB( abp ); }  
        else  
            { // abp is null,  
              // so ap was NOT a pointer to an AB object  
              // do not use abp  
              process_not_AB( ap );  
       }  

If run-time type information has been disabled, i.e. -features=no%rtti, (See Chapter 5, "RTTI"), the compiler converts dynamic_cast to static_cast and issues a warning.
If exceptions have been disabled (See Chapter 4, "Exception Handling"), the compiler converts dynamic_cast<T&> to static_cast<T&> and issues a warning. The dynamic cast to a reference may require an exception in normal circumstances.
Dynamic cast is necessarily slower than an appropriate design pattern, such as conversion by virtual functions. See Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma et al.
http://docs.sun.com/app/docs/doc/802-5660/6i9debhps?l=zh&q=workshop&a=view
c++的return返回 阅读详情

相关推荐

eval() 执行模型输出:国产推理服务 Xinference 工具调用解析 RCE(CVE-2026-61539,CVSS 10.0)

eval() 执行模型输出:国产推理服务 Xinference 工具调用解析 RCE(CVE-2026-61539,CVSS 10.0) TL;DR AI 推理服务 Xinference(Xor

Starry-SkyJing的博客 42

DeepSeek Harness 系列(02):万物皆插件——Cordis 核心设计深度解读

dsh 的所有能力都建立在 Cordis 插件框架之上。这篇文章结合真实源码,深度解读 Cordis 五个核心机制:Plugin、Context、Service、Event、Effect——每个机制讲清楚「是什么、怎么用、为什么这么设计」。读完之后,dsh 的一切都会豁然开朗。

Cheson的专栏 490

C语言怎么样?难学吗?

其实C语言并没有想象中的那么难,很多人刚开始接触时觉得很难是因为之前没有接触过类似这样的课程,其实它就是一门语言而已,只不过是给机器使用的,所以刚开始一般人的思维转不过来

qq2227918581的博客 200

c语言保留标识符

不管是。

mingtiauigena的博客 274

开发图形界面Tkinter、wxPython、PyQt、PySide选哪一个

Python GUI选框架,不是挑工具而是定路线。很多人以为随便找个库就能上手,结果做一半卡死在许可证或打包上。明明代码写得差不多了,却因为选错了起点,最后全重来。

2601_96229748的博客 189

【网络编程 Day2】TCP 通信核心:三次握手、核心 API、C/S 架构与粘包问题全梳理

面向连接:通信前必须通过三次握手建立连接,通信结束通过四次挥手断开可靠传输:有确认机制、超时重传、排序、流量控制、拥塞控制,保证数据不丢、不乱、不重复面向字节流:数据被看作连续的字节流,没有消息边界,会出现粘包全双工:同一个连接建立后,双方可以同时发送和接收数据,两条数据流独立TCP 连接有两条独立的数据流(A→B 和 B→A),可以同时收发,互不干扰。同一个 fd 既能调用 send 也能调用 recv,这就是全双工。TCP 是面向字节流的,没有消息边界。

2401_89475491的博客 822

C++聊天软件服务器 客户端代码分享

基于 Linux epoll + Qt 从零实现的轻量级即时通讯系统,支持聊天、好友、历史记录与文件传输。

sweetikelike的博客 249

VSCode C/C++环境设置

本文介绍了在VSCode中配置C/C++开发环境的完整流程:通过下载MinGW-w64工具链,安装C/C++及C/C++ Runner扩展,配置tasks.json与launch.json实现编译、运行与调试。重点说明了使用快捷键(如Ctrl+Shift+B编译、F5调试)及解决中文路径导致GDB报错的方法。适合初学者快速搭建高效C/C++开发环境。

念致达的博客 118

【SQLite3 数据库】从安装、SQL 操作到 C/C++ API 实战

1.在线安装 sudo apt-get install sqlite3 sudo apt-get install libsqlite3-dev。当select查询数据时,每找到一条数据,callback就会被触发一次;数据库中的数据,通过select查询出时,统一按照字符串处理;callback必须要有返回值,返回0,表示正常;创建数据库:sqlite3 xxx.db。

2301_79651221的博客 132

windows上CRNN-CTC 进行NCNN识别训练转换部署的全流程避坑操作手册

windows上CRNN-CTC 进行NCNN识别训练转换部署的全流程避坑操作手册

qianniulaoren的博客 238

C 语言 “mem”系列内存操作函数全景解析

C语言 mem 系列函数以字节为单位操作内存,不依赖 '\0',可处理任意数据类型。六大标准函数:memset(仅适合清零)、memcpy(无重叠)、memmove(支持重叠)、memccpy、memcmp、memchr。另有 GNU 扩展如 memmem、mempcpy 等。核心原则:不确定重叠时用 memmove,memset 仅用于清零。mem 系列比 str 更底层通用,是处理二进制数据的利器。

Guangyu536的博客 567

C++速通2

int a = 3;int b = 4;// 声明名字空间int main()int a = 1;// 1// ::表示全局作用域 2// 3// 4return 0;```一个函数使用virtual关键字修饰,就是虚函数,虚函数是函数覆盖的前提。在QtCreator中使用斜体字。```cpppublic:// 虚函数cout << "动物爱吃饭" << endl;

qq_63858767的博客 428

C++ std::queue<float> 完整教程

std::queue是front()back()push()pop()

谢谢大家的关注和点赞!这里只有纯纯的知识干货,没有一句废话。希望能实实在在帮到大家~要是觉得有用,别忘了给我点支持哟,你 58

C++第一课

你暂时不用背它。

qq_56657939的博客 107

STL基础语法

后进先出,只能在栈顶插入删除元素。

m0_65163985的博客 206

MAIN.c(1): warning C318: can’t open file ‘STC8G.H’ 报错 解决 分析

编译STC8G1K08-38I-TSSOP20时出现warning C318: can't open file 'STC8G.H',因Keil找不到头文件。解决方法:以管理员身份运行STC-ISP,进入【Keil仿真设置】,点击“添加STC单片机到Keil中”,选择Keil安装目录(如D:\software\KEILC51),系统将自动复制STC8G.H至C51\INC\STC。随后在Keil中配置Include Paths为C:\Keil_v5\C51\INC\STC,即可成功包含头文件并消除警告。校验路

dlj1656955044的博客 123

Linux下服务器端开发流程及相关工具介绍(C++)

本组对外提供 HTTP 服务,以 C++/Java 服务器开发为主,辅以少量 perl、shell 脚本;基于 ABS 打包 rpm 包,内部 yum 源存放,通过金字塔自动化发布。开发环境为 RHEL x86_64,代码默认 GBK 编码。介绍 Linux 任务管理:Ctrl+z、bg、jobs、fg、kill 管理后台任务;推荐 screen 实现会话保活;构建工具含 Make、CMake、Bazel;正则调试可使用[regexr.com](https://regexr.com)

sheep404的博客 143

C++修炼】智能指针使用及原理

本文深入剖析C++智能指针的设计原理与使用场景。文章从手动管理内存的痛点出发,引出RAII资源管理思想,并系统讲解C++标准库中auto_ptr、unique_ptr、shared_ptr和weak_ptr四种智能指针的特点与适用场景。通过模拟实现,揭示auto_ptr的管理权转移、unique_ptr的独占所有权以及shared_ptr基于引用计数的共享管理机制。针对shared_ptr的循环引用问题,详细阐述weak_ptr的弱引用解决方案;同时分析shared_ptr引用计数的线程安全问题及原子化处理

Meanlong_的博客 187

[C++] 深入理解红黑树:封装set与map

本文基于GCC源码分析set和map共用红黑树模板,通过仿函数提取key,适配不同容器;模拟实现迭代器、插入查找及map的operator[],重点阐述中序遍历下迭代器增减的节点跳转逻辑,实现代码复用。

Tairitsu_青云 1万+
上一篇: static_cast、dynamic_cast、const_cast和reinterpret_cast总结
下一篇: C++ reinterpret_cast,const_cast等 显式类型转换总结
Qsir
博客等级 码龄24年 364粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值