高效C/C++之十:Coverity修复问题:尽量多使用 c++强制类型转化

【关注我,后续持续新增专题博文,谢谢!!!】

上一篇我们讲了

        这一篇我们开始讲 高效C/C++之十:Coverity修复问题:尽量多使用 c++强制类型转化

目录

【关注我,后续持续新增专题博文,谢谢!!!】

一、背景

二、:尽量多使用 c++强制类型转化

    2.1:static_cast 静态类型转换(编译时检查)

    2.2 :dynamic_cast 动态类型转换(运行时检查)

    2.3 :const_cast 去只读属性转换(const 转化)

    2.4 :reinterpret_cast 重解析类型转换(强制转化)(慎用)

【关注我,后续持续新增专题博文,谢谢!!!】


一、背景

异常代码

异常代码
Metadata::getMetadata((camera_metadata_t*)metaVirtualAddr, m_vendorTAG, "com.result.data", &data);
正确代码
Metadata::getMetadata(static_cast<camera_metadata_t*>(metaVirtualAddr), m_vendorTAG, "com.result.data", &data);

二、:尽量多使用 c++强制类型转化

    2.1:static_cast 静态类型转换(编译时检查)

可以用隐式转化的地方,都可以用 static_cast, 如果类型不支持 static_cast 会编译检查,会报错,比 c 风格的多了检查的步骤;与以下三个 c++的转化比,速度快一些;可以用于派生类和基类之间指针或引用的转换。

进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;

进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。

char a = 'a';
int b = static_cast<char>(a);//正确,将 char 型数据转换成 int 型数据
double *c = new double;
void *d = static_cast<void*>(c);//正确,将 double 指针转换成 void 指针
int e = 10;
const int f = static_cast<const int>(e);//正确,将 int 型数据转换成 const int 型数据
const int g = 20;
int *h = static_cast<int*>(&g);//编译错误,static_cast 不能转换掉 g 的 const 属性

类上行和下行转换:
if(Derived *dp = static_cast<Derived *>(bp)){//下行转换是不安全的
  //使用 dp 指向的 Derived 对象  
}
else{
  //使用 bp 指向的 Base 对象  
}
if(Base*bp = static_cast<Derived *>(dp)){//上行转换是安全的
  //使用 bp 指向的 Derived 对象  
}
else{
  //使用 dp 指向的 Base 对象  
}

   

    2.2 :dynamic_cast 动态类型转换(运行时检查)

dynamic_cast<type*>(e)
dynamic_cast<type&>(e)
dynamic_cast<type&&>(e)

主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast 和 static_cast 的效果是一样的;

在进行下行转换时,dynamic_cast 具有类型检查的功能,比 static_cast 更安全。

dynamic_cast 是唯一无法由旧式语法执行的动作,也是唯一可能耗费重大运行成本的转型动作。

(1)指针类型
举例,Base 为包含至少一个虚函数的基类,Derived 是 Base 的共有派生类,如果有一个指向 Base 的指针 bp,我们可以在运行时将它转换成指向 Derived 的指针,代码如下:
if(Derived *dp = dynamic_cast<Derived *>(bp)){
  //使用 dp 指向的 Derived 对象  
}
else{
  //使用 bp 指向的 Base 对象  
}
值得注意的是,在上述代码中,if 语句中定义了 dp,这样做的好处是可以在一个操作中同时完成类型转换和条件检查两项任务。

(2)引用类型
因为不存在所谓空引用,所以引用类型的 dynamic_cast 转换与指针类型不同,在引用转换失败时,会抛出 std::bad_cast 异常,该异常定义在头文件 typeinfo 中。
void f(const Base &b){
 try{
   const Derived &d = dynamic_cast<const Base &>(b);  
   //使用 b 引用的 Derived 对象
 }
 catch(std::bad_cast){
   //处理类型转换失败的情况
 }
}

    2.3 :const_cast 去只读属性转换(const 转化)

用来修改类型的 const(唯一有此能力的 C++-style 转型操作符)或 volatile 属性。除了 const 或 volatile 修饰之外,new_type 和 expression 的类型是一样的。

1、常量指针被转化成非常量的指针,并且仍然指向原来的对象;

2、常量引用被转换成非常量的引用,并且仍然指向原来的对象;

3、const_cast一般用于修改底指针。如const char *p形式。

const int g = 20;
int *h = const_cast<int*>(&g);//去掉 const 常量 const 属性
const int g = 20;
int &h = const_cast<int &>(g);//去掉 const 引用 const 属性
const char *g = "hello";
char *h = const_cast<char *>(g);//去掉 const 指针 const 属性

    2.4 :reinterpret_cast 重解析类型转换(强制转化)(慎用)

new_type 必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值)。

reinterpret_cast 意图执行低级转型,实际动作(及结果)可能取决于编辑器,这也就表示它不可移植。

【关注我,后续持续新增专题博文,谢谢!!!】

下一篇讲解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一起搞IT吧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值