1.static_cast(隐式类型转换)
static_cast是一种强制类型转换操作符,编译器对任何类型的隐式转换都可以用static_cast来完成。
当编译器执行隐式类型转换时一般会给出警告(可能会损失精度):
这时候使用static_cast相当于明确告诉编译器这种损失精度的转换是程序员知情的,而不是因为疏忽,所以不会给出警告。
把精度大的类型转换为精度小的类型,static_cast使用位截断进行处理。
static_cast可以用于基类与派生类的指针或引用类型之间的类型转换,不过static_cast不会进行类型检查,可能会出现指向基类对象的基类指针强转成派生类指针这种情况,是不安全的。
2.const_cast
const_cast也是一种强制类型转换操作符,不过它是用来对类型的const属性进行转换。
除了添加const或删除const特性,使用const_cast符来执行其他任何类型的转换都会引起编译错误。
另外,只有使用const_cast才能将const性质性质转化掉。试图使用其他三种形式的强制转换都会导致编译时的错误。
示例:
1、当一个函数的参数不是const类型,而且函数也不会对参数的值进行修改,我们要传一个const类型的变量进去,就可以用到const_cast,直接传是不行的。
需要加上const_cast:
2、当定义了一个非const类型的变量,但是用了const类型的指针指向它,且我们想通过这个指针去修改变量的值,一般来说是不行的,这时候就可以用const_cast去除指针的const属性
int main()
{
int a = 10;
const int *p = &a;
int * q = const_cast<int *>(p);
*q = 20;
cout << *q;//20
return 0;
}
3.dynamic_cast
dynamic_cast是一种特殊的强制类型转换操作符,它支持运行时识别指针或引用。
dynamic_cast提供RTTI(Run-Time Type Information),也就是运行时类型识别。使用dynamic_cast需要编译器启动“运行时类型信息”这一选项,vs默认启动了这一选项。
dynamic_cast主要用于“安全地向下转型”,即将基类对象的指针或者引用安全的转换为派生类的指针或者引用。
对于“向下转型”有两种情况:
1、基类指针所指对象是派生类类型的,这种转换是安全的;
2、基类指针所指对象为基类类型,在这种情况下dynamic_cast在运行时做检查,转换失败,返回结果为0;
示例:
例如将指向基类对象的基类指针强制转换为派生类指针,
使用dynamic_cast转换的Base类至少带有一个虚函数
class Base
{
public:
virtual void show(){};
int a;
};
class test: public Base
{
public:
void show()
{
cout << b;
}
int b;
};
int main()
{
Base* base2 = new Base;
if (test* test1 = dynamic_cast<test*>(base2))
{
cout << "成功";
}
else
{
cout << "失败";
}
delete base2;
return 0;
}
输出:
对于引用类型:
dynamic_cast依旧是常用于“安全的向下转型”。与指针不同的是,因为并不存在空引用,所以引用的dynamic_cast检测失败时会抛出一个bad_cast异常:
class Base
{
public:
virtual void show(){};
int a;
};
class test: public Base
{
public:
void show()
{
cout << b;
}
int b;
};
int main()
{
Base base1;
Base & base2 = base1;
try
{
test &test1 = dynamic_cast<test &>(base2);
}
catch (bad_cast)
{
cout << "转换失败";
}
return 0;
}
输出:
4.reinterpret_cast
reinterpret_cast还需要再做研究