const_cast
- 去除表达式的const性质
- const_cast是唯一能将const性质转化掉的操作符,但执行其他任何类型的转换都会引起编译错误。
单纯的把常量转为变量是没多少意义的,也就是这种代码:
12 |
const int con =12;int cc= static_cast<int>(con); |
直接用变量或者mutable就好了。
如果定义了一个非const的变量,却使用了一个指向const值的指针来指向它(不规范的风格),在进程的某处我们想改变这个变量的值了,但手头只持有指针,这是const_cast就可以用到了:
1234 |
int constant = 26;const int* const_p = &constant;int* modifier = const_cast<int*>(const_p);*modifier = 3; |
这并不是一个好的设计,还是应该遵从这样的原则:使用const_cast去除const限定的目的绝对不是为了修改它的内容,只是出于无奈,所以最好少用转型。
如果有一个函数,它的形参是non-const类型变量,而且函数不会对实参的值进行改动,这时我们可以使用类型为const的变量来调用函数,也就用到const_cast了。
123456789 |
void InputInt(int * num){ cout<<*num<<endl;}int main(){ const int constant = 21; InputInt(const_cast<int*>(&constant));} |
dynamic_cast
dynamic_cast用于类继承层次间的指针或引用转换。和qobject_cast
类似,用于执行“安全的向下转型“,也即是基类对象的指针或引用转换为同一继承层次的其他指针或引用。至于“向上转型”,本身就是安全的,尽管可以使用dynamic_cast进行转换,但这是没必要的。
向下转型有两种情况。一种是基类指针所指对象是派生类类型的,这种转换是安全的;另一种是基类指针所指对象为基类类型,在这种情况下dynamic_cast在运行时做类型检查,转换失败,返回结果为0;
最常用的情况是这样:
大专栏 5个cast转型 class="gutter">
123 |
Base* bb = new Derive();Derive* dd = dynamic_cast<Derive*>(bb);dd->test(); |
使用dynamic_cast转换的基类至少带有一个虚函数,否则会报错:error: C2683: “dynamic_cast”:“Base”不是多态类型
。虚函数表是是dynamic_cast操作符转换能够进行的前提条件。当类没有虚函数表的时候,dynamic_cast无法使用RTTI
,不能通过编译。
dynamic_cast在基类和派生类指针之间转换时,会遍历整个继承体系进行类型检查,因此dynamic_cast在执行效率上比static_cast要差一些,但安全性好。比如4级的继承结构,dynamic_cast<Base>
将会调用4次strcmp才能确定最终的那个子类型,尤其避免连续使用转型,用虚函数代替这种情况。
static_cast
类似于C风格的强制转换。无条件转换,静态类型转换。用于:
- 基类和子类之间转换:其中子类指针转换成父类指针是安全的;但父类指针转换成子类指针是不安全的,此时建议用dynamic_cast。
- 基本数据类型转换,例如double, int, char, float等,不能进行无关类型(如非基类和子类)指针之间的转换。
12 |
double a = 1.999;int b = static_cast<double>(a); //相当于a = b ; |
大多数的编译器都会给出一个警告:从“double”转换到“int”,可能丢失数据。static_cast可以明确告诉编译器,这种损失精度的转换是在知情的情况下进行的
- 把空指针转换成目标类型的指针
1234 |
double a = 1.999;void * vptr = & a;double * dptr = static_cast<double*>(vptr);cout<<*dptr<<endl;//输出1.999 |
- 把任何类型的表达式转换成void类型。
- static_cast不能去掉类型的const、volitale属性(用const_cast)。
static_cast进行的是简单粗暴的转换,static_cast不做运行时的类型检查以保证转换的安全性,所以static_cast不如dynamic_cast安全,其正确性完全由进程员自己保证。
reinterpret_cast
qobject_cast
参考:qobject_cast 分析及QTBUG 20616
原文地址:https://www.cnblogs.com/liuzhongrong/p/12000102.html