涉及到四个:
static_cast<TYPE>、reinterpret_cast<TYPE>、dynamic_cast<TYPE>、const_cast<TYPE>
使用建议
1)static_cast静态类型转换,编译的时c++编译器会做编译时的类型检查;隐式转换;
基本类型转换,父子类之间合理转换
2)若不同类型之间,进行强制类型转换,用reinterpret_cast<>() 进行重新解释
建 议:
C语言中 能隐式类型转换的,在c++中可用 static_cast<>()进行类型转换。因C++编译器在编译检查一般都能通过;C语言中不能隐式类型转换的,在c++中可以用 reinterpret_cast<>() 进行强制类型解释。
总结:static_cast<>()和reinterpret_cast<>() 基本上把C语言中的 强制类型转换给覆盖,注意reinterpret_cast<>()很难保证移植性。
3)dynamic_cast<>(),动态类型转换,安全的虚基类和子类之间转换;运行时类型检查
4)const_cast<>(),去除变量的只读属性
最后的忠告:程序员必须清楚的知道: 要转的变量,类型转换前是什么类型,类型转换 后是什么类型,转换后有什么后果。
1.static_cast<TYPE>
用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。上行指针或引用(派生类到基类)转换安全,下行不安全
Detail:
首先什么是上行,什么是下行?
从派生类到基类的指针或引用转换被称为上行转换或隐式转换;
从基类到派生类的指针或引用转换被称为下行转换或显式转换
代码示例:
背景:
基类Animal,虚函数cry
继承类Dog、Cat
class Animal
{
public:
virtual void cry() = 0; //虚函数
};
class Cat :public Animal
{
public:
void cry()
{
cout << "喵喵..." << endl;
}
};
class Dog :public Animal
{
public:
void cry()
{
cout << "汪汪..." << endl;
}
};
-
用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
代码示例:
把空指针转换成目标类型的空指针
代码示例:
把任何类型的表达式转换成void类型
代码示例:
2.reinterpret_cast<TYPE>
重新解释类型(挂羊头,卖狗肉) 不同类型间的互转,数值与指针间的互转
用法: TYPE b = reinterpret_cast <TYPE> ( a )
TYPE必须是一个指针、引用、算术类型、函数指针.
算术类型:整形、浮点型、枚举、字符
忠告:滥用 reinterpret_cast 运算符可能很容易带来风险。 除非所需转换本身是低级别的,否则应使用其他强制转换运算符之一。
代码示例:
1.数值与指针之间的转换
可以把数值转化为指针,把指针转化为数值 ,这是static_cast做不到的
2.不同类型指针和引用之间的转换
PS:完全没有关系的两个类之间(例如两个派生类)类型转换不能使用static_cast,但是可以用reinterpret_cast
reinterpret_cast可以实现派生类之间的强制类型转换,static_cast不行
引用强转
3.dynamic_cast<TYPE>
动态类型转换
-
将一个基类对象指针cast到继承类指针,dynamic_cast 会根据基类指针是否真正指向继承类指针来做相应处理。失败返回null,成功返回正常cast后的对象指针;
-
将一个基类对象引用cast 继承类对象,dynamic_cast 会根据基类对象是否真正属于继承类来做相应处理。失败抛出异常bad_cast
注意:dynamic_cast在将父类cast到子类时,父类必须要有虚函数一起玩。
代码示例:
基类中一定要虚函数
通过dynamic_cast判断传进来的是猫还是狗.
如果是引用的话,需要用try catch 捕捉bad_cast错误
4.const_cast<TYPE>
用于去const属性
const_cast 中的类型必须是指针、引用或指向对象类型成员的指针
警告:去掉常量限定符之前,保证指针所指向的内存能够修改,不能修改则会引起异常。
p添加了const,无法将修改字符串
可以利用const_cast将const char*转换为char*
代码示例:
可以直接修原字符串(函数传入char*)
注意这里传入的是char*而不是const char*,如果str是const char*则执行时会报错,因为常量字符串是存在常量区内的,不允许程序进行修改