目录
12--C++的类型转换
1、C语言中的类型转换
2、C++中的四种类型转换(区分C语言)
A、static_cast ->隐式类型转换
B、reinterpret_cast ->显式类型转换
C、const_cast ->const指针类型转换为普通指针
D、dynamic_cast ->将基类指针向下转型
3、RTTI(运行时类型识别)(RTTI-Run-time Type identification)
4、习题:
C++中的四种类型转换分别是哪些?
请说明这四种类型转换的应用场景。
类型转换是编程中常见的操作,它允许我们在不同的数据类型之间进行转换。在C++中,类型转换不仅关系到程序的正确性,还关系到程序的效率和安全性。本文将深入探讨C++中的类型转换机制,包括隐式类型转换、显式类型转换以及C++特有的强制类型转换。
在C语言中,类型转换分为隐式类型转换和显式类型转换两种。隐式类型转换由编译器自动完成,而显式类型转换则需要程序员手动指定。然而,C语言的类型转换存在一些问题,比如隐式类型转换可能导致数据精度丢失,而显式类型转换的不透明性使得跟踪错误的转换变得困难。
int
类型的数据赋值给 float
类型时,int
会被隐式转换为 float
。但是,如果隐式转换会导致数据丢失或不兼容,编译器会报错。(float)intValue
将 intValue
显式转换为 float
类型。显式类型转换可以是安全的,也可以是不安全的,这取决于转换的类型和数据值。显式类型转换的一个例子是:
int a = 10;
double b;
b = (double)a; // 显式地将int类型的a转换为double类型
隐式类型转换的一个例子是:
int a = 10;
float b = a; // 隐式地将int类型的a转换为float类型
为了解决C语言类型转换可视性比较差的问题,C++引入了四种命名的强制类型转换操作符:static_cast
、reinterpret_cast
、const_cast
和dynamic_cast
。这些操作符提供了更高的类型转换可视性,使得代码更加清晰和安全。
static_cast
用于非多态类型的转换,即静态转换。它可以执行编译器隐式执行的任何类型转换,但不能用于两个不相关的类型之间。
double x = 3.1415926;
cout << (int)x << endl;
int a = static_cast(x); // static_cast对应隐式类型转换——数据的含义没有发生变化
cout << a << endl;
reinterpret_cast
允许对操作数的位模式进行低层次的重新解释,适用于将一种类型转换为另一种不同的类型。
//x = reinterpret_cast(a); // reinterpter_cast代表对应的类型含义发生变化 不能互用
//cout << x << endl;
int* p = reinterpret_cast(a); // reinterpret_cast对应强制类型转化
cout << p << endl;
const_cast
的主要作用是移除或添加变量的const
属性,使得可以对原本不可修改的变量进行赋值操作。
volatile const double pi = x; // volatile声明避免pi被当作宏替换 值无法改变
double* _pi = const_cast(&pi); // const_cast对应const指针的转化 必须是指针!
*_pi *= 2;
cout << pi << endl; // pi通过_pi被同步改变了
dynamic_cast
用于将父类对象的指针或引用转换为子类对象的指针或引用,这是动态转换的一种形式。它在转换前会进行检查,确保转换的安全性。
易错1:dynamic_cast要求被转换的对象中必须有虚函数表(才能进行RTTI)
易错2:dynamic_cast转换的对象是——派生类对象被切片放入基类对象中,希望向下转型回派生类对象,如果直接对基类指针进行向下转型,dynamic_cast将返回nullptr(跟malloc一样,先进行检查再使用指针)
class A
{
public:
virtual void base()
{
cout << "A()" << endl;
}
};
class B : public A
{
public:
};
int main()
{
/********************************************************************/
A* pa = new A();
B* pb = new B();
A* p = pb; // 派生类发生截断
//a = b;
//a.base();
// pb = (B*)pb; // 不安全 没有合法性检查 可能会越界访问派生类未开辟的空间
p->base();
B* pp = dynamic_cast(p);
pp->base();
/********************************************************************/
return 0;
}
C++通过typeid
运算符、dynamic_cast
运算符和decltype
关键字来支持运行时类型识别。
RTTI允许程序在运行时获取对象的类型信息,这对于多态性和类型安全的转换至关重要。
答:static_cast
、reinterpret_cast
、const_cast
、dynamic_cast
。
static_cast
:用于非多态性类型转换,如基本数据类型之间的转换。reinterpret_cast
:用于位模式的重新解释,如指针类型之间的转换。const_cast
:用于修改对象的const
属性,进行必要的赋值操作。dynamic_cast
:用于安全的向下转型,即从父类指针或引用转换到子类。