在 C 语言中需要进行强制类型转换可以使用以下方式,在 C++中当然还是可以使用。
( 类型 ) 变量 ;
例如:
int a = 48 ;char * b = ( char *)& a ;
c++除了能使用
c
语言的强制类型转换外,还新增了四种强制类型转换:
static_cast
、
dynamic_cast
、
const_cast
、
reinterpret_cast
,主要运用于继承关系类间的强制转化,语法为:
static_cast < 类型 >( 变量 )dynamic_cast < 类型 >( 变量 )const_cast < 类型 >( 变量 )reinterpret_cast < 类型 >( 变量 )
静态转换 static_cast
示例:
int c = 100 ;char b = static_cast < char >( c );
static_cast 相当于传统的 C 语言里的强制转换,该运算符把变量转换为指定类型,用来强迫隐式转换,例如 non-const 对象转为 const 对象,编译时检查,用于非多态的转换,可以转换指针及其他,但没有运行时类型检查来保证转换的安全性。
可以用于基本类型的转换
, 与传统的强转相比,static_cast 意图更加明显,带有类型检查,它主要有如下几种用法:
①
用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把 int 转换成 char,把 int 转换成 enum。这种转换的安全性也要开发人员来保证。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成 void 类型。
不过要注意的是 static_cast 不能转换掉变量的 const、volatile、或者__unaligned 属性。而且用 static_cast 不能对不同类型的指针进行转换
重解释转换 reinterpret_cast
示例:
int a = 48 ;char * b = reinterpret_cast < char *>(& a );
reinterpret_cast 的待转换的类型必须是一个指针、引用、算术类型、函数指针或者成员指 针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值),
用于指针间的转换
。
reinterpret_cast 意图执行低级转型,实际动作(及结果)可能取决于编辑器,这也就表示它不可移植。另外,static_cast 和 reinterpret_cast 的区别主要在于多重继承,比如
class A
{
public:
int m_a;
};
class B
{
public:
int m_b;
};
class C : public A, public B {};
int main()
{
C c;
printf("%p, %p, %p", &c, reinterpret_cast<B*>(&c), static_cast<B*>(&c));
return 0;
}
前两个的输出值是相同的,最后一个则会在原基础上偏移 4 个字节,这是因为 static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址(c 里面有 m_a,m_b,转换为 B*指针后指到 m_b 处),而 reinterpret_cast 却不会做这一层转换。因此, 在进行继承类的转换时你需要谨慎使用 reinterpret_cast。
去常量转换 const_cast
示例:
const int x = 5 ;const int * a = & x ;int * b = const_cast < int *>( a );* b = 7 ;
const_cast,
用于修改类型的 const 或 volatile 属性
。该运算符用来修改类型的 const(唯一有此能力的 C++转型操作符)或 volatile 属性。当然除了 const 或 volatile 修饰之外,类型要一样才
行,也就是你不可以 const char 转 int,你只能 const char 转 char。
动态转换 dynamic_cast
dynamic_cast
用于多态类型之间的转换
,当我们用基类指针指向派生类时,指针访问的是基类中的函数,我们可以使用动态转换把他转换成派生类。前提是基类中有虚函数(生成虚表,使其多态)
dynamic_cast <type*>(e)dynamic_cast <type&>(e)dynamic_cast <type&&>(e)
type 必须是一个类类型,在第一种形式中,type 必须是一个有效的指针,在第二种形式中,type 必须是一个左值,在第三种形式中,type 必须是一个右值。在上面所有形式中,e 的类型必须符合以下三个条件中的任何一个:e 的类型是是目标类型 type 的公有派生类、e 的类型是目标 type 的共有基类或者 e 的类型就是目标 type 的的类型。如果一条 dynamic_cast 语句的转换目标是指针类型并且失败了,则结果为 0。如果转换目标是引用类型并且失败了,则 dynamic_cast 运算符将抛出一个 std::bad_cast 异常(该异常定义在 typeinfo 标准库头文件中)。e也可以是一个空指针,结果是所需类型的空指针。
dynamic_cast 主要用于类层次间的上行转换(子类转父类)和下行转换(父类转子类),还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast 和 static_cast 的效果是一样
的;
在进行下行转换时,dynamic_cast 具有类型检查的功能,比 static_cast 更安全。
dynamic_cast 是唯一无法由 C 语言语法执行的动作,也是唯一可能耗费重大运行成本的转型动
作。
备注:
新式转换较旧式转换更受欢迎。 原因有二,一是新式转型较易辨别,能简化“找出类型系统在哪个地方被破坏”的过程; 二是各转型动作的目标愈窄化,编译器愈能诊断出错误的运用。尽量少使用转型操作
,尤其是 dynamic_cast,耗时较高,会导致性能的下降,尽量使用其他方法替代。