• C/C++中的类型转换


    目录

    一、C语言中的类型转换

    1、隐式类型转换

    2、强制类型转换

    C语言类型转换的特点:

    二、C++中的类型转换

    1、static_cast

    2、reinterpret_cast

    3、const_cast

    4、dynamic_cast

    四种类型转换的特点:


    一、C语言中的类型转换

    1、隐式类型转换

    适用与两个相关的类型之间的自动转换,类型不相关时编译器会识别出来并报错。

    1. double a = 3.14;
    2. int b = a;//隐式类型转换
    3. int* p = nullptr;
    4. b = p;//两个不相关的类型无法进行隐式类型转换

     

    2、强制类型转换

    如果想让两个不相关之间的类型发生转换,此时需要显示的取强制类型转换。

    1. int d = 3;
    2. int *pd = nullptr;
    3. d = (int)pd;//强制类型转换

    C语言类型转换的特点:

    1、转换的格式很简单。

    2、转换的可视性较差。

    3、没有错误检查,容易出错。

    二、C++中的类型转换

    为了解决C语言类型的转换的问题,C++引入了四种命名的强制类型转换操作符。

    1、static_cast

    static_cast用于非多态类型的转换,负责相关连的两个类型之间进行类型转换,与C语言中的隐式类型转换类似。

    1. double val1 = 3.3;
    2. int val2 = static_cast<int>(val1);//用于两个相关类型的转换

    2、reinterpret_cast

    强制转换,用于两个不相关的类型的转换,简单来说什么类型都可以转,这种转换不对结果做保证,容易出问题。

    1. typedef void(*fuc)(void);
    2. void* test(int num)
    3. {
    4. cout << "test: " << num << endl;
    5. return nullptr;
    6. }
    7. int main()
    8. {
    9. fuc val3 = reinterpret_cast(test);//把一个void*返回值、int类型的参数的函数转换成ret = void和参数为void的函数
    10. val3();
    11. }

    运行结果难以预料。

     

    3、const_cast

    去除变量的常属性只针对指针和引用。

     

    1. const int a = 3; //常变量
    2. int* pa = &a; //这样将a的地址赋值给pa是错的,因为a的地址是const int*类型
    3. //此时可以采用const_cast 来进行强转
    4. const int a = 3;
    5. int* pa = const_cast<int*>(&a);//此时可以把const int* 转换成int*

    补充:如果此时对pa指向的空间修改同时打印a 的值和 *pa的值会发生什么

    1. *pa = 4; // pa指向的空间更改
    2. cout << a << endl; //输出3 编译器的优化,默认从寄存器读取,此时采用volatile关键字修饰
    3. cout << *pa << endl; //输出4

    可以看到a的值确实改变,但为什么会输出3呢?

    原因编译器的优化

    编译器会默认的认为常变量是不会被修改的,所以会将他的值拷贝到寄存器当中,每次获取a的值都是从寄存器中去获取,而不是从内存中读取。常变量a他在内存中的栈区间内,这个a的值是已经被修改了。

    如果要避免这种情况的发生,需要用关键字volatile,他的作用是防止编译器去优化,每次读取数据从内存中读取数据

     

    4、dynamic_cast

    用于类的向上向下转换。

    向上转换:子类向基类转换。

    ​向下转换:基类向子类转换。

    前提:dynamic_cast只能用于含有虚函数的类。

    dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0。

    1. class Base
    2. {
    3. public:
    4. virtual void functon(void){}
    5. int a;
    6. };
    7. class Child :public Base
    8. {
    9. public:
    10. int b;
    11. };
    12. void test(Base* ptr)
    13. {
    14. Child* pc1 = (Child*)ptr;//C语言中的强转
    15. Child* pc2 = dynamic_cast(ptr);//C++中的转换,会判断是否能够转换成功
    16. cout << "pc1: " << pc1 << endl;
    17. cout << "pc2: " << pc2 << endl;
    18. }
    19. //main函数
    20. Base b;
    21. Child c;
    22. test(&b);//给一个基类的地址
    23. test(&c);//给一个子类的地址

    向下转换是一个很不安全的过程,转换的时候会进行类型检查,类型相等成功转换,类型不等转换失败。但是C语言中的强转不管结果怎样,很危险。

     如果传入一个基类的地址进去的时候,强转之后 如果此时访问一下子类的成员,会出现错误。

    四种类型转换的特点:

    1、转换明确,调用什么样的类型转换一眼便知道

    2、可以进行错误检查。

  • 相关阅读:
    CentOS下安装MySQL 8.1及备份配置
    机器学习(监督学习)笔记
    k8s UAT改环境
    JavaScript_notes
    Docker-基础
    HTTPS安全机制解析:如何保护我们的数据传输
    flutter 适配屏幕宽高工具
    使用开源的zip.cpp和unzip.cpp实现压缩包的创建与解压(附源码)
    机器学习-期末复习
    python 获取android 应用使用情况
  • 原文地址:https://blog.csdn.net/weixin_43164548/article/details/125905726