首页 > 编程语言 >C++ 静态类型转换和动态类型转换的区别

C++ 静态类型转换和动态类型转换的区别

时间:2024-10-05 21:14:39浏览次数:5  
标签:类型转换 转换 静态 dynamic C++ cast Base static

  1. 静态类型转换(static_cast

    • 概念
      • static_cast是C++中的一种类型转换操作符,用于在编译时进行类型转换。它主要用于具有明确的、编译器可以在编译阶段确定的类型转换关系的情况。这种转换通常在相关类型之间进行,例如基本数据类型之间的转换,或者在类层次结构中的向上转换(将派生类指针或引用转换为基类指针或引用)。
    • 例子
      • 基本数据类型转换
        • int类型转换为double类型:
          int numInt = 5;
          double numDouble = static_cast<double>(numInt);
          
        • double类型转换为int类型(会截断小数部分):
          double numDouble = 3.14;
          int numInt = static_cast<int>(numDouble);
          
      • 类层次结构中的向上转换
        • 假设有基类Base和派生类Derived
          class Base {};
          class Derived : public Base {};
          Derived d;
          Base* b = static_cast<Base*>(&d);
          
    • 特点
      • 编译器在编译时进行检查,如果转换不合法(例如转换没有意义或者不符合类型转换规则),会产生编译错误。
      • 对于基本数据类型,它执行的转换类似于隐式类型转换,但更加明确。对于类类型的转换,它不会进行运行时的类型检查,只是简单地进行类型调整。
  2. 动态类型转换(dynamic_cast

    • 概念
      • dynamic_cast也是C++中的一种类型转换操作符,主要用于在类的层次结构中进行安全的向下转换(将基类指针或引用转换为派生类指针或引用)。与static_cast不同的是,dynamic_cast在运行时进行类型检查,以确保转换的安全性。
    • 例子
      • 假设有基类Base(包含至少一个虚函数以支持运行时多态)和派生类Derived
        class Base { virtual void f() {} };
        class Derived : public Base {};
        Base* b = new Derived();
        Derived* d = dynamic_cast<Derived*>(b);
        if (d!= nullptr) {
            // 转换成功,可以安全使用d
        } else {
            // 转换失败
        }
        
        • 如果将基类指针实际指向的是基类对象而不是派生类对象,那么dynamic_cast会返回nullptr(对于指针类型)。如果是引用类型的转换失败,则会抛出std::bad_cast异常。例如:
          Base* b = new Base();
          Derived* d = dynamic_cast<Derived*>(b);
          if (d == nullptr) {
              std::cout << "Conversion failed." << std::endl;
          }
          
    • 特点
      • 运行时类型检查增加了程序的安全性,确保在转换时对象的实际类型与转换目标类型相匹配。
      • 由于需要在运行时进行类型检查,会带来一定的性能开销。这种开销主要是因为它需要在对象的虚函数表(vtable)中查找类型信息。
  3. 区别

    • 检查时间
      • static_cast在编译时进行类型检查,而dynamic_cast在运行时进行类型检查。
    • 安全性
      • static_cast在进行类层次结构的转换时,不进行运行时的类型验证,可能会导致不安全的转换。例如,将一个基类指针错误地转换为派生类指针,可能会在后续使用中引发未定义行为。dynamic_cast则通过运行时检查确保转换的安全性。
    • 使用场景
      • static_cast适用于编译器能够在编译阶段确定转换合法性的情况,如基本数据类型转换和类层次结构中的向上转换(这种转换通常是安全的,因为派生类对象可以被看作是基类对象的一种特殊情况)。dynamic_cast主要用于在类层次结构中进行向下转换,并且需要在运行时确保转换的正确性。
    • 性能
      • 由于dynamic_cast需要在运行时进行类型检查,涉及到虚函数表的查询等操作,所以会有一定的性能开销。而static_cast在编译时就完成了转换操作,没有运行时的额外开销。

标签:类型转换,转换,静态,dynamic,C++,cast,Base,static
From: https://www.cnblogs.com/androidsuperman/p/18448478

相关文章

  • C++ 重解释类型转换
    概念在C++中,reinterpret_cast被称为重新解释类型转换。它是一种强制类型转换操作符,用于将一种数据类型转换为另一种几乎完全不相关的数据类型。这种转换不进行任何数据的重新格式化或转换操作,只是简单地将数据的二进制表示重新解释为新的类型。语法语法形式为:reinterpret_......
  • C++ 常类型转换
    概念在C++中,常类型转换主要涉及到const_cast操作符,用于在特定情况下对const(常量)限定符进行处理。const关键字在C++中有重要意义,它表示被修饰的对象是常量,不能被修改。但在某些特殊情况下,需要在不破坏常量性语义的前提下,进行与常量相关的操作转换。const_cast的使用示例调......
  • C++ 类型强转
    static_cast基本概念static_cast主要用于在相关类型之间进行转换,这些类型之间存在某种隐式转换关系。它在编译时进行检查,是一种比较安全的类型转换方式。适用场景基本数据类型转换:例如将int转换为double,或者double转换为int(会截断小数部分)。intnumInt=5;doublenumD......
  • C++ 模板详解(一)
    C++模板模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。模板是一种对类型进行参数化的工具;通常有两种形式:函数模板和类模板;函数模板针对仅参数类型不同的函......
  • c++之auto关键字的注意点(涉及decltype)
    1.基本规则auto会根据初始化表达式的类型推导出变量的类型。如果初始化的是值类型,auto推导出的也是值类型。如果初始化的是引用类型,auto会忽略引用类型,并推导出被引用对象的类型。如果初始化表达式是常量(const),且auto不是引用类型,推导出的类型会去掉const限定符。vo......
  • 帝国CMS在IIS环境开启TAG伪静态后,中文TAG提示“TAG不存在”的最后解决方法!
    如果你尝试了多种解决方案仍然无法解决帝国CMSTAG伪静态中文提示“TAG不存在”的问题,可以尝试以下方案:解决方案打开 index.php 文件。修改变量获取方式。具体操作步骤打开 index.php 文件:打开 /e/tags/index.php 文件。修改变量获取方式:查找以下代码:......
  • 欧拉筛解释(含C++代码)
    intprime[MAXN];//质数列表boolisPrime[MAXN];//标记是否为质数(0表示是,1表示不是)intcnt;//prime表长/*对于任意合数m,可写作m=p*k(p为m的最小质因子,k为m/p,m、k>1且为整数,k>p(p为最小质因子,k为其它几个质因子相乘,每个质因子都比p大,所以k>p))*///欧拉筛(使每个合数......
  • C++ 命名空间
    概念在C++中,命名空间(namespace)是一种将代码中的标识符(如变量名、函数名、类名等)进行分组和隔离的机制。它可以避免不同代码模块之间的命名冲突,提高代码的可维护性和可移植性。命名空间的定义基本语法为:namespace命名空间名称{//在这里定义变量、函数、类等}例......
  • C++-练习-52
    题目:这个练习让您编写处理数组和结构的函数,下面是程序的框架,请提供其中描述的函数,以完成该程序#include<iostream>usingnamespacestd;constintSLEN=30;structstudent{charfullname[SLEN];charhobby[SLEN];intooplevel;}; intgetinfo(studentpa[],i......
  • vs code如何配置C/C++环境,实现完美运行.c/.cpp文件,以及终端乱码问题
    环境配置在VisualStudioCode(VSCode)中安装了C/C++ExtensionPack后,你可以通过以下步骤来运行C++文件:安装编译器配置编译任务:在VSCode中,你可以创建一个编译任务来编译你的C++文件。这通常通过创建一个tasks.json文件来完成。你可以通过以下步骤创建这个......