C++提供了四个转换运算符:const_cast,static_cast,reinterpret_cast,dynamic_cast

本文深入探讨了C++中智能指针的转换方法,包括static_pointer_cast、dynamic_pointer_cast、const_pointer_cast和reinterpret_pointer_cast的使用场景与注意事项。同时,详细解析了const_cast、reinterpret_cast、static_cast和dynamic_cast的语法与应用,强调了不同类型转换的安全性和适用范围。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

c++智能指针转化:static_pointer_cast、dynamic_pointer_cast、const_pointer_cast、reinterpret_pointer_cast

c++智能指针转化:static_pointer_cast、dynamic_pointer_cast、const_pointer_cast、reinterpret_pointer_cast_Glücklichste的博客-CSDN博客

(684条消息) C++ 中 const_cast 作用详解_c++ const_cast_有温度的程序员的博客-CSDN博客

 unsigned(as);

(int)ret;

  1. static_cast :编译时期的静态类型检查static_cast静态转换相当于C语言中的强制转换,但不能实现普通指针数据(空指针除外)的强制转换,一般用于父类和子类指针、引用间的相互转换。没有运行时类型检查来保证转换的安全性。

①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。不管是否发生多态,父子之间互转时,编译器都不会报错。

  • 进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
  • 进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的,但是编译器不会报错。

②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。 ③把空指针转换成目标类型的空指针。 ④把任何指针类型转换成空指针类型。 ⑤可以对普通数据的const和non_const进行转换,但不能对普通数据取地址后的指针进行const添加和消去。 ⑥无继承关系的自定义类型,不可转换,不支持类间交叉转换。 另外,static_cast不能转换掉原有类型的const、volatile、或者 __unaligned属性。(前两种可以使用const_cast 来去除)。

  1. dynamic_cast:运行时的检查 动态转换的类型和操作数必须是完整类类型或空指针、空引用,说人话就是说,只能用于类间转换,支持类间交叉转换,不能操作普通数据。 主要用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换, ①进行上行转换(把派生类的指针或引用转换成基类表示)是安全的,允许转换; ②进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的,不允许转化,编译器会报错; ③发生多态时,允许互相转换。 ④无继承关系的类之间也可以相互转换,类之间的交叉转换。 ⑤如果dynamic_cast语句的转换目标是指针类型并且失败了,则结果为0。如果转换目标是引用类型并且失败了,则dynamic_cast运算符将抛出一个std::bad_cast异常
  2. const_cast const_cast用于强制去掉不能被修改的常数特性,其去除常量性的对象一般为指针或引用。
  3. reinterpret_cast 在C++语言中,reinterpret_cast主要有几种强制转换用途:将指针或引用转换为一个足够长度的整型、将整型转换为指针或引用类型。 更详细见 C++的四种强制转换
  4. 为什么不使用C的强制转换 ? C的强制转换表面上看起来功能强大什么都能转,但是转化不够明确,不能进行错误检查,容易出错。

作者:红尘氵梦
链接:c++ 常用面试题整理(不定时更新)_牛客网
来源:牛客网

C++中的四种转换:static_cast、const_cast、reinterpret_cast、dynamic_cast_神游天外的博客-CSDN博客

static_cast用法浅析

static_cast用法浅析_static_cast<char*>_Citronnelle2的博客-CSDN博客

C++可不可以用static_cast来基类指针转子类指针?

C++可不可以用static_cast来基类指针转子类指针? - 知乎

C++中const_cast的作用和缘由_扭高达的博客-CSDN博客

用const_cast来去除const限定

于是const_cast就出来消灭const,以求引起程序世界的混乱。

下边的代码就顺利编译功过了: const int constant = 21;
const int* const_p = &constant;
int* modifier = const_cast<int*>(const_p);
*modifier = 7;

reinterpret_cast语法:reinterpret_cast<type-id>(expression)

reinterpret_cast:允许将任何指针转换为任何其他指针类型。也允许将任何整数类型转换为任何指针类型以及反向转换。

滥用reinterpret_cast运算符可能很容易带来风险。除非所需转换本身是低级别的,否则应使用其他强制转换运算符之一。

reinterpret_cast运算符可用于char*到int*或One_class*到Unrelated_class*之类的转换,这本身并不安全。

reinterpret_cast的结果不能安全地用于除强制转换回其原始类型以外的任何用途。在最好的情况下,其他用途也是不可移植的。

reinterpret_cast运算符不能丢掉const、volatile或__unaligned特性。

reinterpret_cast运算符将null指针值转换为目标类型的null指针值。

reinterpret_cast的一个实际用途是在哈希函数中,即,通过让两个不同的值几乎不以相同的索引结尾的方式将值映射到索引。

reinterpret_cast通常为运算对象的位模式提供较低层次上的重新解释。reinterpret_cast本质上依赖机器。要想安全地使用reinterpret_cast必须对涉及的类型和编译器实现转换的过程都非常了解。

        auto* header = reinterpret_cast<Header*>(ptr);

static_cast语法:static_cast<type-id>(expression)

static_cast:仅根据表达式中存在的类型,将expression转换为type-id类型。此运算符可用于将指向基类的指针转换为指向派生类的指针等操作。此类转换并非始终安全。

通常使用 static_cast 转换数值数据类型,例如将枚举型转换为整型或将整型转换为浮点型,而且你能确定参与转换的数据类型。 static_cast转换安全性不如dynamic_cast转换,因static_cast不执行运行时类型检查,而dynamic_cas执行该检查。对不明确的指针的 dynamic_cast将失败,而static_cast的返回结果看似没有问题,这是危险的。尽管 dynamic_cast转换更加安全,但是dynamic_cast只适用于指针或引用,而且运行时类型检查也是一项开销。dynamic_cast 和static_cast运算符可以在整个类层次结构中移动指针。然而,static_cast完全依赖于转换语句提供的信息,因此可能不安全。

static_cast可以反向执行隐式转换,可用于任何隐式允许的转换类型,而在这种情况下结果是不确定的。这需要程序员来验证static_cast转换的结果是否安全。

static_cast可用于将int转换为char。但是,得到的char可能没有足够的位来保存整个int值。同样,这需要程序员来验证static_cast转换的结果是否安全。

static_cast运算符还可用于执行任何隐式转换,包括标准转换和用户定义的转换。

static_cast 运算符可以将整数值显式转换为枚举类型。如果整型值不在枚举值的范围内,生成的枚举值是不确定的。

static_cast运算符将null指针值转换为目标类型的null指针值。

任何表达式都可以通过static_cast运算符显式转换为void类型。目标void类型可以选择性地包含const、volatile或__unaligned特性。

static_cast运算符无法转换掉const、volatile或 __unaligned特性。

只有在确信代码将正常运行的时候,在性能关键代码中使用 static_cast。如果必须在发布模式下使用static_cast,请在调试版本中用 safe_cast(C++ 组件扩展)替换它以确保成功。

任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。

            if (len < static_cast<size_t>(ptr - data) + 4)

if (dynamic_cast<SrsOnMetaDataPacket*>(pkt)) {
            SrsOnMetaDataPacket* metadata = dynamic_cast<SrsOnMetaDataPacket*>(pkt);

class Base {
public:
    Base( );
    virtual ~Base( );
};

class Derived : public Base {
public:
    Derived( );
    ~Derived( );
};

void foo( ) {
    Base *pB;
    Derived *pD2 = (Derived *) pB;     // 违规
}



修复

class Base {
public:
    Base( );
    virtual ~Base( );
};

class Derived : public Base {
public:
    Derived( );
    ~Derived( );
};

void foo( ) {
    Base *pB;
    Derived *pD1 = dynamic_cast<Derived*>( pB );   // OK
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值