将类型名作为强制转换的语法是C语言保留下来的,C++有自己独有的类型转换,就是四种cast。
它们都有着统一的语法,即xx_cast<typename>(expression)
,可以将expression转换成typename的类型。
static_cast
顾名思义,静态转换,通常用于内置类型的转换。但是不能用于不同类型的指针/引用之间的转换(唯一的例外是可以将void*
指转换成其他类型的指针),也不能将整型转换为指针型。
如果想对类进行转换,需要类之间具有继承的关系。比如说A,B,C类,B类继承自A类。那么B类和A类之间是可以互相转换的,而C类就不能转换成A类,反之亦然。
如果对应的类重载了强制类型转换运算符T,那么可以用static_cast
将其转换成T类型。
const_cast
const_cast
的功能比较简单,可以去除const属性。
比如将const指针转换成普通指针,将const引用转换成普通引用等。
const string s = "abc";
string &p = const_cast<string&>(s);
string *ps = const_cast<string*>(&s);
reinterpret_cast
这是一个类似C的转换,它可以将任何内置类型转换成其他任何数据类型,也可以将任何指针类型转换成其他类型。
顾名思义,它其实只是让对该对象解释的方式改变了,实际上并没有改变该对象的任何比特。
这种转换的功能最强大,同时也最危险。
dynamic_cast
上面三个转换都是在编译期发生的,dynamic_cast
是唯一一个在运行期发生的强制类型转换。
这个转换专门用于将多态父类指针转换成子类指针,在转换过程中,会检查这种转换是否合法,如果不合法就会返回一个nullptr
。(注意,这里的将父类指针转换成子类指针,前提是父类指针实际上指向的对象是子类,那么才合法)
但是对于非多态父类指针转换成子类指针,dynamic_cast
是做不到的。这是因为这种转换无法保证安全。
对于多态类来说,它内部具有虚函数表,可以通过RTTI(运行时类型信息)来确定指针或者引用所指对象的具体类型。而非多态类无法进行这种动态的类型识别,所以无法检查这种转换的安全性。