C++ static_cast、dynamic_cast、const_cast和reinterpret_cast

一、背景由来

这四个关键字代表了c++的四种类型转换运算符

隐式类型转换是安全的,显式类型转换是有风险的。C语言之所以增加强制类型转换的语法,就是为了强调风险,让程序员意识到自己在做什么。但是,这种强调风险的方式还是比较粗放,它并没有表明存在什么风险,风险程度如何。再者,C风格的强制类型转换统一使用(),而()在代码中随处可见,所以也不利于使用文本检索工具(例如 Windows 下的 Ctrl+F、Linux 下的 grep 命令、Mac 下的 Command+F)定位关键代码。

为了使潜在风险更加细化,使问题追溯更加方便,使书写格式更加规范,C++ 对类型转换进行了分类,并新增了四个关键字来予以支持,它们分别是:

关键字 说明
static_cast

static_cast不做运行时的类型检查以保证转换的安全性。

static_cast 是“静态转换”的意思,也就是在编译期间转换,转换失败的话会抛出一个编译错误。

const_cast 用于 const 与非 const、volatile 与非 volatile 之间的转换。
reinterpret_cast 高度危险的转换,这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,但是可以实现最灵活的 C++ 类型转换。
dynamic_cast 借助 RTTI,用于类型安全的向下转型(Downcasting)。


这四个关键字的语法格式都是一样的,具体为:

xxx_cast(data)

newType 是要转换成的新类型,data 是被转换的数据。

例如,老式的C风格的 double 转 int 的写法为:

double scores = 95.5;
int n = (int)scores;

C++ 新风格的写法为:

double scores = 95.5;
int n = static_cast(scores);

二、static_cast

static_cast不仅可以应用到指针和引用上,而且还可以应用到基础数据结构和对象上,典型的应用场景如下:

  • 基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
  • 把空指针转换成目标类型的空指针。
  • 把任何类型的表达式转换成void类型。
  • 用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。

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

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

注意:static_cast不能去掉expression的const、volatile、或者__unaligned属性。

示例1:

char a = 'a';
int b = static_cast(a);//正确,将char型数据转换成int型数据

double *c = new double;
void *d = static_cast(c);//正确,将double指针转换成void指针

int e = 10;
const int f = static_cast(e);//正确,将int型数据转换成const int型数据

const int g = 20;
int *h = static_cast(&g);//编译错误,static_cast不能转换掉g的const属性

 示例2:

class Parents
{
public:
	virtual ~Parents(){}
	/*codes here*/
};

class Children : public Parents
{
	/*codes here*/
};

int main() 
{	
	Children * daughter = new Children();
	Parents * mother = static_cast (daughter); //right, cast with polymorphism
	
	Parents * father = new Parents();
	Children * son = static_cast (father); //no error, but not safe
}

ref:

static_cast用法浅析_wei.zhou的专栏-CSDN博客_static_cast

C++ static_cast、dynamic_cast、const_cast和reinterpret_cast(四种类型转换运算符)

C++标准转换运算符static_cast - Ider - 博客园

你可能感兴趣的:(c/c++,c++)