C语言中的类型转换只需要在变量名前加上想要转化成的变量类型即可;如:
//c风格的类型转换
int a = 1;
double b = 1.1
a = (double)b;
b = (int) a;
但是这种简单的转换方式有一些缺陷:
- 转换过于随意;C风格的类型转换在时,没有任何的限制,容易引起一些未知的问题;
- C风格的类型转换没有统一的关键字和提示符。在代码较多的情况下,排查时容易忽略;
因为C++是兼容C语言的,所以在C++中也可以用C语言的方式来进行类型的转换,但是,C++又不想出现和C语言一样的缺陷和问题,所以C++提供了四种类型转换符来解决C中的类型转换的遗留问题;
这四种类型转换符分别为:
static_cast
dynamic_cast
const_cast
reinterpret_cast
这四种类型转换符本质上都是:类模板
static_cast(静态转换)
-
使用场景:
static_cast用于 基本数据类型之间,有类型指针和void*之间以及基类和派生类之间指针或者引用的转换。 -
使用特点:
- 主要执行非多态的类型转换,可以代替C语言中通常的转换操作。
- 隐式转换建议使用static_cast;
- 不能使用static_cast在有类型指针内部转换;
- 使用static_cast进行父类指针/引用转换成子类的指针/引用时,不安全; -
用法:
static_cast< type-name > (expression)
- 示例:
int main()
{
//1.在基本类型之间进行转换
int a = 1;
double b = 1.1;
a = static_cast<double>(b);
//2.在有类型指针和void*之间进行转换
int* iptr = &a;
void* vptr = static_cast<void*>(iptr);
//3.在基类和派生类之间进行转换
class Base{};
class Derived:public Base {};
Derived* dptr = new Derived();
Base* bptr = static_cast<Base*>(dptr);
dptr = static_cast<Derived*>(bptr);
//4.不可以在有类型指针之间进行转换
int* aptr = &a;
double* dbptr = &b;
//Error aptr = static_cast<int*>(dbptr);
}
dynamic_cast(动态转换)
-
使用场景:
dynamic_cast用于 将对父类指针/引用转换为对子类的指针/引用; -
使用特点:
- 父类必须要有虚函数(构成多态),因为dynamic_cast是在运行时进行类型检查,在运行时类型信息存储在该类的虚表中;
- 使用dynamic_cast进行父类指针/引用转换成子类的指针/引用时,是安全的;
- 使用dynamic_cast对指针进行类型转换。失败时返回NULL,成功时返回转换后的对象指针;
- 使用dynamic_cast对引用进行类型转换。失败时抛出异常,成功时返回转换后的对象引用; -
用法:
dynamic_cast< type-name > (expression)
- 示例:
//基类
class Base
{
public:
virtual int test() {}
};
//派生类
class Derived:public Base
{
public:
virtual int test() {}
};
int main()
{
Base* bptr = new Base();
// 将基类对象指针类型转换为派生类对象指针
Derived* dptr = dynamic_cast<Derived*>(bptr);
Base b;
Base& br = b;
// 将基类对象的引用转换派生类对象的引用
Derived& dr = dynamic_cast<Derived&>(br);
}
const_cast(常量转换)
-
使用场景:
const_cast用于 常量指针/引用与非常量指针/引用之间的转换。 -
使用特点:
- const_cast运算符用于执行只有一种用途的类型转换,即改变值为 const 或 volatile的类型;
- const_cast是四种类型转换符中唯一可以对常量进行操作的转换符。 -
用法:
const_cast< type-name > (expression)
- 示例:
int main()
{
int a = 10;
const int* ptr = &a;
//将常量指针转换为非常量指针,然后可以修改常量指针指向变量的值
int* p1 = const_cast<int*> (ptr);
*p1 = 1;
//将非常量指针转换为常量指针
const int *p2 = const_cast<const int *>(p1);
const int b = 20;
cosnt int& rb = b;
//将常量引用转换为非常量引用
int &rb1 = const_cast<int &>(rb);
// 将非常量引用转换为常量引用
const int &rb2= const_cast<const int &>(rb1);
}
reinterpret_cast(不相关类型的转换)
-
使用场景:
reinterpret_cast用于 任意指针/引用类型 -
使用特点:
- reinterpret_cast用于天生危险的类型转换,比如将int类型的变量变成结构体类型;
- 通常,这样的转换适用于依赖于实现底层编程技术,是不可移植的; -
注意:
reinterpret_cast运算符并不支持所有的类型转换。例如:可以将指针类型转换成足以存储指针表示的整形,但是不能将指针转换成更小的整形或浮点型。
而且,不能将函数指针转换成数据指针,反之亦然。 -
用法:
reinterpret_cast< type-name > (expression)
- 示例:
int main()
{
int a = 100;
// 用在任意指针(或引用)类型之间的转换
double *p = reinterpret_cast<double *>(&a);
// reinterpret_cast能够将指针值转化为整形值
int *ptr = &a;
int pv = reinterpret_cast<int>(ptr);
}