C++ 类型的转换

C++类型转换详解

在 C++编程中,类型转换是一个重要的概念。它允许我们在不同类型的数据之间进行转换,以满足特定的编程需求。C++中的类型转换主要包括隐式类型转换和显式类型转换,同时还有四种命名的强制类型转换操作符。

一、C 语言中的类型转换

在 C 语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化。C 语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换。

1. 隐式类型转化

隐式类型转化是编译器在编译阶段自动进行的,关联比较强的。

那么那些支持隐式类型转换的?
首先是我们熟悉的整形之间的转换(int,char double,有符号,无符号······),整形和浮点数之间的转换,

int i = 1;
double d = i; // 隐式类型转换,将整数 i 转换为浮点数 d

2. 显式类型转化

显式类型转化需要用户自己处理。

那么显示类型转换都有哪些呢?
指针和整形之间的转换,指针之间的转换

int* p = &i;
int address = (int) p; // 显示的强制类型转换,将指针 p 转换为整数 address

然而,C 语言中的类型转换存在一些缺陷,转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换。

二、为什么 C++需要四种类型转换

C 风格的转换格式简单,但有不少缺点:

  1. 隐式类型转化在某些情况下可能会出问题,比如数据精度丢失。
  2. 显式类型转换将所有情况混合在一起,代码不够清晰。

因此,C++提出了自己的类型转化风格,同时为了兼容 C 语言,C++中还可以使用 C 语言的转化风格。

三、C++强制类型转换

标准 C++引入了四种命名的强制类型转换操作符:static_castreinterpret_castconst_castdynamic_cast
虽说C语言的类型转换兼容也可以用,但是C++的目的就是让语法更加规范

1. static_cast

这个就是隐式类型转换,C++中进行了语法的规范化
static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用 static_cast,但它不能用于两个不相关的类型进行转换。

//对应隐式类型转换
double d = 12.34;
int a = static_cast<int>(d); // 将浮点数 d 转换为整数 a

2. reinterpret_cast

同样的,reinterpret英文重新解释的意思,对应的就是强制类型转换。
reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型。

//对应强制类型转换
double d = 12.34;
int a = static_cast<int>(d);
// 这里使用 static_cast 会报错,应该使用 reinterpret_cast
int *p = reinterpret_cast<int*>(a); // 将整数 a 转换为指针 p

3. const_cast

强转中的一种,有风险的去掉const的属性(其实强转也可以,还是那句话C++的目的是为了规范)
const_cast最常用的用途就是删除变量的 const属性,方便赋值。

void Test() {
    const int a = 2;
    int* p = const_cast<int*>(&a);
    *p = 3;
    cout << a << endl;
}

4. 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;
}

需要注意的是,强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是否还有其他不同的方法达到同一目的。如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。强烈建议避免使用强制类型转换。

四、RTTI(了解)

RTTI(Run - time Type identification)即运行时类型识别,C++通过以下方式来支持 RTTI:

  1. typeid运算符。
  2. dynamic_cast运算符。
  3. decltype

五、常见面试题

  1. C++中的 4 种类型转化分别是:static_castreinterpret_castconst_castdynamic_cast
  2. 4 种类型转化的应用场景:
    • static_cast:用于非多态类型的转换,例如基本数据类型之间的转换。
    • reinterpret_cast:用于进行底层的位模式重新解释,通常用于指针和整数之间的转换,或者不同类型指针之间的转换,但这种转换需要谨慎使用,因为它可能会导致未定义的行为。
    • const_cast:主要用于删除变量的 const属性,以便进行赋值操作。
    • dynamic_cast:用于在继承关系中进行安全的向下转型,确保只有在实际对象类型与目标类型匹配时才进行转换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值