在 C 中提供了强制类型转换,不过其实现很简单,而且没有区分具体的使用场景,所以,在编译或者运行阶段可能会出现一些异常,尤其是一旦不注意极易发生异常。
为此,C++ 对于不同的场景进行了划分,由于 C++ 支持面向对象编程,也因此对这一场景进行了优化。本文详细介绍其使用场景。
简介
C++ 支持 C 风格的强制类型转换,无论是什么类型,都可以通过 TypeName VarB = (TypeName)VarA;进行装换,因为不区分具体的场景,所以在某些场景下可能会存在隐患。
所以 C++ 提供了一组可以在不同场合下执行强制转换的函数,主要分成了四种:
const_cast去除const属性,将之前无法修改的变量变为可修改。
static_cast静态类型转换,常用于基本类型转换,例如将int转换成char。
dynamic_cast动态类型转换,多态类之间的类型转换,如子类和父类之间的多态类型转换。
reinterpret_cast重新解释类型,不同类型指针和整型之间的相互转换,没有进行二进制的转换。
在转换时可以通过 TypeName VarB = XXX_cast<TypeName>(VarA);这种方式进行转换,下面详细介绍四种方法的区别。
1、const_cast
通过 const限定该变量的值不能被修改,而const_cast则是强制去掉这种属性。注意,这里去除的不是变量的常量性,而是去除的是指向常量的指针或者引用。
如下,其中有两个错误:1) ptr指向的是常量,不允许对常量进行修改;2) 通过const_cast强制转换对象必须是指针或者引用,不允许变量。
#include <iostream>
int main(void)
{
const int var = 10;
const int *ptr = &var;
int *data;
//*ptr = 20; // ERROR <1>
//int val = const_cast<int>(var); // ERROR <2>
data = const_cast<int *>(ptr);
*data = 20; // OK
std::cout << var << " " << *ptr << " " << *data << std::endl;
std::cout << &var << " " << ptr << " " << data << std::endl;
return 0;
}
如果通过 g++ -std=c++11 -o main main.cc编译,在x86_64机器上的执行结果为。
10 20 20
0x7ffcf79ef4ac 0x7ffcf79ef4ac 0x7ffcf79ef4ac
也就是说,从执行结果上看,首先没有修改常量;其次,所有的地址信息是相同的。原则上来说,常量不修改应该是正常的,虽然我们在使用该方法尝试将其修改。
但是,为什么变量 var没有被修改???
Why !?
在介绍其原因之前,先看看可能的修改策略。可以在声明变量时添加 volatile关键字,也就是将声明修改为如下。