https://blog.csdn.net/qq_22080999/article/details/81279954
1. const_cast<T> (expression) //移除常量性
const_cast 一般用于强制消除对象的常量性。它是唯一能做到这一点的 C++ 风格的强制转型。
2. static_cast<T> (expression) //强制隐式转换
static_cast 可以被用于强制隐型转换(例如,non-const 对象转型为 const 对象,int 转型为 double,等等),它还可以用于很多这样的转换的反向转换(例如,void* 指针转型为有类型指针,基类指针转型为派生类指针),但是它不能将一个 const 对象转型为 non-const 对象(只有 const_cast 能做到),它最接近于C-style的转换。
【补充】:
(隐式类型转换原则):
1)不能损失精度,可以从低精度向高精度转换。
2)自定义对象可以隐式转为父对象。
(隐式类型转换发生情况):
*1)在混合类型的算术表达式中
int ival = 3; double dval = 3.1415 ival + dval; //ival 被提升为double 类型:3.0
*2)用一种类型的表达式赋值
int *pi = NULL; // NULL(0)被转换成了int* 类型的空指针值
*3) 用一个表达式传递给一个函数调用
extern double sqrt(double); sqrt(2); //2被提升为double类型: 2.0
*4) 从一个函数返回一个表达式
double difference(int ival1, int ival2) { return ival1 - ival2; //返回值被提升为double 类型. }
*5) 可以用形参调用构造函数,使从形参类型转为类对象类型
class Test { public: Test(int a); bool isSame(Test other) { return m_val == other.m_val; } private: int m_val; }
Test a(10); cout<<if(a.isSame(10))<<endl; //该语句将返回true
这个例子中的 isSame 是成员函数,用于两个对象之间的比较。但是形参为int时没有报错,是因为编译器在运行到这个函数时,形参int会调用类构造函数,生成一个临时对象,用于执行函数。但是这里要注意,构造函数一定只有一个参数,或其他参数都有默认值。
总之:对于内置类型,低精度的变量给高精度变量赋值会发生隐式类型转换;对于只存在单个参数的构造函数的对象构造来说,函数调用可以直接使用该参数传入,编译器会自动调用其构造函数生成临时对象。
(禁用隐式类型转换):
禁用比较简单,对类的构造函数来说,在前面加上关键字 explicit 修饰即可。
(显式类型转换):
显式类型转换就是强制类型转换,在最前面用括号把目标值的类型括起来即可。
3. dynamic_cast<T> (expression) //安全的向下转型
dynamic_cast 主要用于执行“安全的向下转型(safe downcasting)”,也就是说,要确定一个对象是否是一个继承体系中的一个特定类型。它是唯一不能用旧风格语法执行的强制转型,也是唯一可能有重大运行时代价的强制转型。
4. reinterpret_cast<T> (expression) //低级转型
reinterpret_cast 是特意用于底层的强制转型,导致实现依赖(implementation-dependent)(就是说,不可移植)的结果,例如,将一个指针转型为一个整数。这样的强制转型在底层代码以外应该极为罕见。
【总结】:
旧风格的强制转型依然合法,但是新的形式更可取。
首先,在代码中它们更容易识别(无论是人还是像 grep 这样的工具都是如此),这样就简化了在代码中寻找类型系统被破坏的地方的过程。
第二,更精确地指定每一个强制转型的目的,使得编译器诊断使用错误成为可能。例如,如果你试图使用一个 const_cast以外的新风格强制转型来消除常量性,你的代码将无法编译。
-
【补充】(RTTI:运行时类型检查):
运行时类型检查,在C++层面主要体现在dynamic_cast和typeid.RTTI(Run Time Type Identification)即通过运行时类型识别,程序能够使用基类的指针或引用来检查着这些指针或引用所指的对象的实际派生类型。
【具体实现】:VS中虚函数表的-1位置存放了指向type_info的指针。对于存在虚函数的类型,typeid和dynamic_cast都会去查询type_info。