类型转换
1-类型转换定义
类型转换(Type Conversion)是将一种数据类型转换为另一种数据类型的过程。在C和C++中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与 接收返回值类型不一致时,就需要发生类型转化,总共有两种形式的类型转换:隐式类型 转换和显式类型转换。
2 -类型转换方式
2.1.隐式类型转换
隐式类型转换是由编译器自动执行的类型转换,通常发生在不同数据类型之间进行运算或赋值时。隐式转换主要分为以下几种情况:
--标准转换
标准转换包括以下几种常见的类型转换:
算术转换:例如,将 int
转换为 float
,或 char
转换为 int
。
代码:
int a = 5;
double b = a; // int 转换为 double
指针转换:例如,将派生类指针转换为基类指针(向上转换),或 void*
转换为其他类型的指针。
class Base {};
class Derived : public Base {};
Derived d;
Base* b = &d; // Derived* 转换为 Base*
布尔转换:任何算术类型或指针类型都可以隐式转换为 bool
。
int a = 5;
if (a) { // int 转换为 bool
return true;
}
--用户定义的转换
用户可以通过定义转换构造函数或转换运算符来实现自定义类型之间的隐式转换。
//转换构造函数
class MyClass {
public:
MyClass(int x) { // 转换构造函数
// ...
}
};
MyClass obj = 10; // int 转换为 MyClass
//转换运算符
class MyClass {
public:
operator int() const { // 转换运算符
return 42;
}
};
MyClass obj;
int a = obj; // MyClass 转换为 int
2.2 显式类型转换
c中的强制类型转换
使用 (类型)
的语法进行类型转换。这种方式在C++中能用,但不够安全,容易出错。
double a = 3.14;
int b = (int)a; // C的强制转换
3. C++强制类型转换
标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符: static_cast、reinterpret_cast、const_cast、dynamic_cas
a. static_cast
static_cast
用于在相关类型之间进行转换,如基本数据类型之间的转换、指针的上行转换(派生类指针转换为基类指针)等。它在编译时进行类型检查,较为安全。
double a = 3.14;
int b = static_cast<int>(a); // 基本类型转换
class Base {};
class Derived : public Base {};
Derived d;
Base* b = static_cast<Base*>(&d); // 上行转换
b. dynamic_cast
dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)
向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)
向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)
注意: 1. dynamic_cast只能用于父类含有虚函数的类
2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
class A
{
public :
virtual void f(){}
};
class B : public A
{};
void fun (A* pa)
{
// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回
B* pb1 = static_cast<B*>(pa);
B* pb2 = dynamic_cast<B*>(pa);
cout<<"pb1:" <<pb1<< endl;
cout<<"pb2:" <<pb2<< endl;
}
int main ()
{
A a;
B b;
fun(&a);
fun(&b);
return 0;
}
c. reinterpret_cast
reinterpret_cast
用于进行低级别的、不安全的类型转换,通常用于指针类型之间的转换。它不会进行任何类型检查,转换后的结果依赖于具体的实现和平台。
int a = 10;
int* p = &a;
double* dp = reinterpret_cast<double*>(p); // 不安全的指针转换
d. const_cast
const_cast
用于移除对象的 const
或 volatile
修饰符。它只能用于指针或引用类型,且不能改变对象的实际类型。
const int a = 10;
int& b = const_cast<int&>(a); // 移除 const
b = 20; // 未定义行为,因为 a 是 const
3. 总结
- 隐式转换 由编译器自动执行,适用于安全且自然的类型转换场景,但可能带来精度损失或数据截断的风险。
- 显式转换 由程序员明确指定,提供了更细粒度的控制,但也需要谨慎使用以避免引入错误。
static_cast
是最常用的显式转换方式,适用于大多数类型转换需求。dynamic_cast
用于在类层次结构中进行安全的向下转换。reinterpret_cast
用于低级别的、不安全的转换,需谨慎使用。const_cast
用于移除const
或volatile
修饰符,需谨慎使用以避免未定义行为