用C++中的四个强制类型转换的关键字:static_cast,const_cast,reinterpret_cast,dynamic_cast
- static_cast<类型说明符>(表达式)
- dynamic_cast<类型说明符>(表达式)
- const_cast<类型说明符>(表达式)
- reinterpret_cast<类型说明符>(表达式)
static_cast相当于传统的C语言里的强制转换,任何具有明确定义的类型转换,只要不包括底层const,都可以使用static_const。
1.2 语法用法为 static_cast
该运算符把 expression 转换为 type-id 类型,但没有运行时类型检查来保证转换的安全性
(1)用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
(2)用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
(3)把空指针转换成目标类型的空指针。
(4)把任何类型的表达式转换成void类型。
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属性
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
if(Derived *dp = static_cast2 const_cast 2.1 简介(bp)){//下行转换是不安全的 //使用dp指向的Derived对象 } else{ //使用bp指向的base对象 } if(base*bp = static_cast (dp)){//上行转换是安全的 //使用bp指向的Derived对象 } else{ //使用dp指向的base对象 }
const_cast,用于修改类型的const或volatile属性。只要const_cast 能改变表达式的常量属性,使用其他形式的命名强制类型转换改变表达式的常量属性都将引发编译器错误。
2.2 语法const_cast < type-id > ( expression )
主要是用来去掉const属性,当然也可以加上const属性。主要是用前者,后者很少用
2.3 使用场景该运算符用来修改类型的const(唯一有此能力的C++-style转型操作符)或volatile属性。除了const 或volatile修饰之外, new_type和expression的类型是一样的。
- 常量指针被转化成非常量的指针,并且仍然指向原来的对象;
- 常量引用被转换成非常量的引用,并且仍然指向原来的对象;
- const_cast一般用于修改底指针。如const char *p形式。
const int g = 20; int *h = const_cast(&g);//去掉const常量const属性 const int g = 20; int &h = const_cast (g);//去掉const引用const属性 const char *g = "hello"; char *h = const_cast (g);//去掉const指针const属性
const A *pca1 = new A;
A *pa2 = const_cast(pca1); //常量对象转换为非常量对象
pa2->m_iNum = 200;
错误用法:
常量对象(或基本类型)不可以被转换成非常量对象(或基本类型)
//常量对象被转换成非常量对象时出错 const A ca; A a = const_cast(ca); //不允许 const int i = 100; int j = const_cast(i); //不允许
使用const_cast去掉const属性,其实并不是真的改变原类类型(或基本类型)的const属性,它只是又提供了一个接口(指针或引用)。
3 reinterpret_cast 3.1 简介reinterpret_cast用在任意指针(或引用)类型之间的转换;以及指针与足够大的整数类型之间的转换;从整数类型(包括枚举类型)到指针类型,无视大小。
3.2 语法new_type a = reinterpret_cast
将value的值转成new_type类型的值,a和value的值一模一样,比特位不变。
reinterpret_cast
使用较少,且危险。
3.4 举例int num = 0x00636261;//用16进制表示32位int,0x61是字符'a'的ASCII码 int * pnum = # char * pstr = reinterpret_cast(pnum); cout<<"pnum指针的值: "< (pstr)<
将pnum和pstr两个指针的值输出,两个指针的值是完全相同的,但是输出的内容不同,由于指针类型改变为 char * 导致的。
4 dynamic_cast 4.1 简介将基类的指针或引用安全地转换成派生类的指针或引用,并用派生类的指针或引用调用非虚函数。如果是基类指针或引用调用的是虚函数无需转换就能在运行时调用派生类的虚函数。
4.2 语法dynamic_cast < type-id > ( expression)
该运算符把expression转换成type-id类型的对象。Type-id可以是类的指针、类的引用或者void*。如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。
4.3 使用场景 4.4 举例(1)向上转换:
class B { ... }; class C : public B { ... }; class D : public C { ... }; void f(D* pd) { C* pc = dynamic_cast(pd); // ok: C 是一个直接的基类 // pc 指向 pd 的 C 子对象 B* pb = dynamic_cast(pd); // ok: B 是一个间接的基类 // pb 指向 pd 的 B 子对象 ... } (2)如果 type-id 是一个 void* ,运行时检查将决定表达式的实际类型。结果是一个到 expression 指向的完整对象
class A { ... }; class B { ... }; void f() { A* pa = new A; B* pb = new B; void* pv = dynamic_cast(pa); // pv 指向一个 A 类型的对象 ... pv = dynamic_cast (pb); // pv 指向一个 B 类型的对象 } 如果 type-id 不是 void* ,运行时检查指向 expression 的对象能否转换为指向 type-id 类型的对象。
如果 expression 类型是 type-id 的基类,运行时检查是否 expression 实际是一个指向 type-id 类型的完整对象,如果是,结果返回指向 type-id 类型的完整对象,否则返回 NULL 。
5 沿用C的转换方式C++是兼容C的,因此C语言中的强制类型转换在C++中同样适用,具体使用方法可以参照下面的代码示例:
float valueA = 3.0f; int valueB = (int) valueA;二、其他常见类型转换 2.1 const void *ptr 转换成 string类型const char* ptrNew = (const char*)ptr; //强制转换为 char类型
std::string test(ptrNew,ptrNew.size());
2.2 string 转换为const char* ptrstring test="1233";
const char* ptr = const_cast
(test.c_str(); 参考文献:
【1】C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast:C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast - SpartacusIn21 - 博客园



